Excel JavaScript API を使用して Excel アドインのコメントを管理する

この記事では、Excel JavaScript API を使用して、特定のセルにスレッド化されたコメントを作成する方法、返信する方法、コメントを編集または削除する方法、会話を解決する方法、作成者のメタデータの読み取り方法、メンションの追加方法、コメント イベントへの応答を行う方法について説明します。

Excel JavaScript API では、コメントは 1 つのコメントで始まり、応答を含めることができるスレッドです。 各スレッドは 1 つのセルに関連付けられています。 スレッドディスカッションではなく従来のノート動作が必要な場合は、「 Excel JavaScript API を使用してノートを操作する」を参照してください。

コメントでできること

Excel コメント API を使用して、次の手順を実行します。

  • セルに新しいコメント スレッドを追加します。
  • 既存のスレッドで応答を追加、編集、削除します。
  • スレッドを解決または再度開きます。
  • 作成者と作成のメタデータを読み取る。
  • メンションを含むコメントを作成します。
  • コメントの追加、変更、削除イベントをリッスンします。

コメント オブジェクト モデルについて

Workbook.comments プロパティは、ブック内のコメントを追跡します。 このプロパティは、ユーザーが作成したコメントとアドインによって作成されたコメントの両方を含む CommentCollection を返します。 Worksheet.comments プロパティを使用して、ワークシート レベルでコメントにアクセスすることもできます。

Comment オブジェクトは、1 つのセルの完全なスレッドを表します。 そのスレッド内の応答は、コメントの replies コレクションに CommentReply オブジェクトとして格納されます。

コメント スレッドを追加する

セルでスレッド化された会話を開始するには、 CommentCollection.add を使用します。 メソッドは、最大 3 つのパラメーターを受け入れます。

  • cellAddress: コメントを追加するセル。 このパラメーターには、文字列または Range オブジェクトを指定できます。 範囲は 1 つのセルである必要があります。
  • content: コメント テキスト。 テキスト形式のコメントには文字列を使用します。 メンションを含むコメントには CommentRichContent オブジェクトを使用します。
  • contentType: コンテンツ タイプを指定する ContentType 値。 既定値は ContentType.plain です。

次の例では、セル A2 でレビュー スレッドを開始します。 アドインによって作成されるコメントは、現在のユーザーに帰属されることに注意してください。

await Excel.run(async (context) => {
    const comments = context.workbook.comments;
    comments.add("MyWorksheet!A2", "Please confirm the Q2 revenue total.");
    await context.sync();
});

注:

範囲に複数のセルが含まれている場合、 InvalidArgument エラーがスローされます。

コメント スレッドに応答を追加する

アドインで既存のディスカッションを続行する必要がある場合は、 CommentReplyCollection.add を使用します。 応答は追加された順序で表示され、現在のユーザーにも属性が付けられます。

次の例では、セル A2 のスレッドに応答を追加します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    comment.replies.add("Thanks for the reminder!");
    await context.sync();
});

コメント スレッドを編集する

Comment.contentを更新して、スレッドの最初のエントリを変更します。 CommentReply.contentを更新して、特定の返信を変更します。

次の例では、セル A2 のメイン コメントを更新します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    comment.content = "Please confirm the Q2 revenue total before we publish this workbook.";
    await context.sync();
});

返信を編集する

アドインがスレッド内の以前の応答を修正する必要がある場合は、このパターンを使用します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    const reply = comment.replies.getItemAt(0);

    reply.content = "Thanks. I rechecked the total and it is correct.";
    await context.sync();
});

コメント スレッドを削除する

セルからスレッド全体を削除するには、 Comment.delete() を使用します。 コメントを削除すると、そのスレッド内のすべての応答も削除されます。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    comment.delete();
    await context.sync();
});

返信を削除する

1 つの応答を削除し、スレッドの残りの部分を保持する必要がある場合は、 CommentReply.delete() を使用します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    const reply = comment.replies.getItemAt(0);

    reply.delete();
    await context.sync();
});

コメント スレッドを解決して再度開く

Comment.resolved プロパティを使用して、ディスカッションに引き続き注意が必要かどうかを追跡します。 値を true に設定してスレッドを解決するか、 false して再度開きます。 CommentReply.resolved は読み取り専用であり、常に親スレッドの状態と一致します。

次の例では、セル A2 のスレッドを解決します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    comment.resolved = true;
    await context.sync();
});

コメント メタデータの読み取り

各コメントには、作成者や作成日などのメタデータが格納されます。 アドインによって作成されたコメントは、現在のユーザーによって作成されます。

次の例では、セル A2 のコメントの作成者の電子メール、作成者名、作成日をログに記録します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");

    comment.load(["authorEmail", "authorName", "creationDate"]);
    await context.sync();

    console.log(`${comment.creationDate.toDateString()}: ${comment.authorName} (${comment.authorEmail})`);
});

応答メタデータの読み取り

応答には、最初のコメントと同じメタデータが格納されます。 次の例では、セル A2 のスレッドの最新の応答を取得し、作成者情報をログに記録します。

await Excel.run(async (context) => {
    const comment = context.workbook.comments.getItemByCell("MyWorksheet!A2");
    const replyCount = comment.replies.getCount();
    await context.sync();

    if (replyCount.value === 0) {
        console.log("The thread has no replies.");
        return;
    }

    const reply = comment.replies.getItemAt(replyCount.value - 1);
    reply.load(["authorEmail", "authorName", "creationDate"]);
    await context.sync();

    console.log(`Latest reply: ${reply.creationDate.toDateString()}: ${reply.authorName} (${reply.authorEmail})`);
});

ユーザーのメンション

アドインで同僚にコメントのタグを付け、メール通知をトリガーする必要がある場合は、メンションを使用します。 メンションを含むコメントを作成するには、CommentRichContent オブジェクトで CommentCollection.add を呼び出し、contentType パラメーターを ContentType.mention に設定します。

richContent文字列内の各メンションを<at id="{replyIndex}">{mentionName}</at>として書式設定します。

現在、メンションの正確な名前のみをメンションリンクのテキストとして使用できます。 名前の短縮バージョンのサポートは、後で追加されます。

次の例では、単一のメンションを持つコメントをセル A1 に追加します。

await Excel.run(async (context) => {
    const mention = {
        email: "kakri@contoso.com",
        id: 0,
        name: "Kate Kristensen"
    };

    const commentBody = {
        mentions: [mention],
        richContent: `<at id="0">${mention.name}</at> Can you review the forecast?`
    };

    // An `InvalidArgument` error is thrown if the range contains multiple cells.
    context.workbook.comments.add("MyWorksheet!A1", commentBody, Excel.ContentType.mention);
    await context.sync();
});

コメント イベントを処理する

ユーザーがブックを更新するときに、アドインがディスカッションに対応する必要がある場合は、コメント イベントを使用します。 コメント イベント は、 CommentCollection オブジェクトで発生します。

次のハンドラーを登録します。

  • onAdded 新しいコメント スレッドが作成されたとき。
  • onChanged コメントまたは返信が追加、編集、削除、解決、または再度開かれた場合。
  • onDeleted コメント スレッドが削除されたとき。

1 つの操作が複数のコメントに影響を与える場合、イベント引数には commentDetailsに複数の項目が含まれます。 次のサンプルでは、わかりやすくするために最初の項目のみを使用します。 一般的なイベント ガイダンスについては、「 Excel JavaScript API を使用したイベントの操作」を参照してください。

コメント追加イベントを処理する

onAdded イベントは、1 つ以上のコメントがコレクションに追加されたときに発生します。 応答が既存のスレッドに追加されても起動しません。

await Excel.run(async (context) => {
    const comments = context.workbook.worksheets.getActiveWorksheet().comments;

    comments.onAdded.add(commentAdded);
    await context.sync();
});

async function commentAdded(event) {
    await Excel.run(async (context) => {
        const addedComment = context.workbook.comments.getItem(event.commentDetails[0].commentId);
        addedComment.load(["content", "authorName"]);
        await context.sync();

        console.log(`A comment was added. ID: ${event.commentDetails[0].commentId}. Content: ${addedComment.content}. Author: ${addedComment.authorName}`);
    });
}

コメント変更イベントを処理する

onChanged イベントは、次の場合に発生します。

  • コメントの内容が更新されます。
  • コメント スレッドが解決されます。
  • コメント スレッドが再度開きます。
  • 応答がコメント スレッドに追加されます。
  • コメント スレッドで応答が更新されます。
  • コメント スレッドから応答が削除されます。
await Excel.run(async (context) => {
    const comments = context.workbook.worksheets.getActiveWorksheet().comments;

    comments.onChanged.add(commentChanged);
    await context.sync();
});

async function commentChanged(event) {
    await Excel.run(async (context) => {
        const changedComment = context.workbook.comments.getItem(event.commentDetails[0].commentId);
        changedComment.load(["content", "authorName"]);
        await context.sync();

        console.log(`A comment was changed. ID: ${event.commentDetails[0].commentId}. Content: ${changedComment.content}. Author: ${changedComment.authorName}`);
    });
}

コメント削除イベントを処理する

onDeleted イベントは、コメントがコレクションから削除されたときに発生します。 コメントが削除されると、そのメタデータは使用できなくなります。 アドインで削除されたスレッドを追跡する必要がある場合は、 CommentDeletedEventArgs.commentDetails の ID を使用します。

await Excel.run(async (context) => {
    const comments = context.workbook.worksheets.getActiveWorksheet().comments;

    comments.onDeleted.add(commentDeleted);
    await context.sync();
});

async function commentDeleted(event) {
    console.log(`A comment was deleted. ID: ${event.commentDetails[0].commentId}`);
}

関連項目