从 Office Add-In 按钮操作工作表

Manipulate Worksheet from Office Add-In Button

我刚刚进入 Office.JS,我正在尝试执行一个基本操作,即单击功能区中的一个按钮 UI 并在电子表格上做一些事情。我发现的所有示例都与单击单元格和使用 =CONTOSO... 执行 return 变量的功能有关。我的宏没有一个以这种方式工作,它们要么有一个用于输入的用户窗体,要么只是“做”某事。

我已经设法在功能区中创建了一个新选项卡,其中包含一个应该调用函数 getdata 的按钮,它实际上不是一个函数,而是一个 module/sub 我只是想在单元格 A1.

中输入 FOO

这是我对默认设置所做的更改 运行 yo office

manifest.xml:

          <ExtensionPoint xsi:type="PrimaryCommandSurface">
            <CustomTab id="TabCustom1">
            <!-- <OfficeTab id="TabData"> -->
            <Label resid="TabGroup.Label"/>
              <Group id="CommandsGroup">
                <Label resid="CommandsGroup.Label"/>
                <!-- Can only use 1, or default = Far Right
                <InsertAfter>TabReview</InsertAfter>
                <InsertBefore>TabReview</InsertBefore>
                -->
                <Icon>
                  <bt:Image size="16" resid="Icon.16x16"/>
                  <bt:Image size="32" resid="Icon.32x32"/>
                  <bt:Image size="80" resid="Icon.80x80"/>
                </Icon>
                <Control xsi:type="Button" id="TaskpaneButton">
                  <Label resid="TaskpaneButton.Label"/>
                  <Supertip>
                    <Title resid="TaskpaneButton.Label"/>
                    <Description resid="TaskpaneButton.Tooltip"/>
                  </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="ShowTaskpane">
                    <TaskpaneId>ButtonId1</TaskpaneId>
                    <SourceLocation resid="Taskpane.Url"/>
                  </Action>
                </Control>
                <Control xsi:type="Button" id="DoButton">
                  <Label resid="DoButton.Label"/>
                  <Supertip>
                    <Title resid="DoButton.Label"/>
                    <Description resid="DoButton.Tooltip"/>
                  </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>getData</FunctionName>
                  </Action>
                </Control>
              </Group>
              <!-- </OfficeTab> -->
            </CustomTab>
          </ExtensionPoint>

...

      <bt:ShortStrings>
        <bt:String id="Functions.Namespace" DefaultValue="CONTOSO"/>
        <bt:String id="CommandsGroup.Label" DefaultValue="Group Label"/>
        <bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
        <bt:String id="TaskpaneButton.Label" DefaultValue="TaskPane Button label"/>
        <bt:String id="DoButton.Label" DefaultValue="Do Button label"/>
        <bt:String id="TabGroup.Label" DefaultValue="Custom Tab"/>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the Custom Tab and click the 'Button label' button to get started."/>
        <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane"/>
        <bt:String id="DoButton.Tooltip" DefaultValue="Click to Run A Function"/>
      </bt:LongStrings>

我什至不确定在哪里添加这个功能,我在 functions.js 中搞砸了,但同样,这一切似乎都是为了在单元格中输入 =FUNCNAME。谁能指出我正确的方向?

谢谢

当加载项命令使用 ExecuteFunction 操作时,FunctionFile 元素指定包含 JavaScript 到 运行 代码的文件。 FunctionFile 元素的 resid 属性设置为 HTML 文件,其中包含您的加载项命令所需的所有 JavaScript 文件。您不能 link 直接到 JavaScript 文件。您只能 link 到 HTML 文件。文件名指定为 Resources 元素中的 Url 元素。例如:

<DesktopFormFactor>
    <FunctionFile resid="residDesktopFuncUrl" />
    <ExtensionPoint xsi:type="PrimaryCommandSurface">
      <!-- information about this extension point -->
    </ExtensionPoint>

    <!-- You can define more than one ExtensionPoint element as needed -->
</DesktopFormFactor>

如果单击功能区按钮时您的功能仍然不可用,很可能您需要通过以下方式使其对外部调用者可见(我如何为 Outlook 加载项做到这一点):

function getGlobal() {
  return typeof self !== "undefined"
    ? self
    : typeof window !== "undefined"
    ? window
    : typeof global !== "undefined"
    ? global
    : undefined;
}

const g = getGlobal() as any;

// The add-in command functions need to be available in global scope
g.action = action;

终于明白了!只花了几个小时阅读,我不明白为什么他们不从这样简单的事情开始,但是文档开始时通过任务窗格制作 table,过滤 table,冻结 header 行,然后最后在底部我找到了一个名为 "protect a worksheet" 的部分,它与 运行 通过“任务窗格”无关,只需单击按钮即可。

我调试的另外几个问题是,如果我选择 Excel Custom Functions Add-in project(这是我不需要的 =CONTOSO 命名空间的来源,我无法让它工作)它必须是 Office Add-in Task Pane project。我还学会了使用 npm startnpm run start:desktop 因为我注意到有时它会使用 productiondevelopment.

最后,学习如何清除所有内容很重要,例如进入“信任中心”并单击“下次办公室启动清除缓存”并删除所有内容 --> %LOCALAPPDATA%\Microsoft\Office.0\Wef\

这是我通过 Office.JS 单击功能区中的按钮将“hello world”插入单元格 A1 的基本说明。

yo office

选择项目类型:Office Add-in任务窗格项目

选择脚本类型:JavaScript

你想给你的 add-in 起什么名字?我的办公室 Add-in

您想支持哪个 Office 客户端应用程序? Excel

manifest.xml

在现有 <Control></Control>

结束后插入
                <Control xsi:type="Button" id="HelloWorldButton">
                  <Label resid="HelloWorld.Label"/>
                  <Supertip>
                    <Title resid="HelloWorld.Label"/>
                    <Description resid="HelloWorld.Tooltip"/>
                  </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>helloworld</FunctionName>
                  </Action>
                </Control>
....

  <bt:String id="HelloWorld.Label" DefaultValue="Ribbon helloworld Func" />

...

  <bt:String id="HelloWorld.Tooltip" DefaultValue="Click to run helloworld func" />

commands.js

在函数操作(事件)结束后插入 }

function helloworld(args) {
  Excel.run(function (context) {
    var ws = context.workbook.worksheets.getActiveWorksheet();
    var range = ws.getRange("A1");
    range.values = "Hello World!";
    range.select();

    return context.sync();
  }).catch(function (error) {
    console.log("Error: " + error);
    if (error instanceof OfficeExtension.Error) {
      console.log("Debug info: " + JSON.stringify(error.debugInfo));
    }
  });
  args.completed();
}

在文档底部:

g.helloworld = helloworld;

测试:

npm start