有关 Excel 中的共同创作

了解有关 Excel 中的共同创作的工作方式以及需要如何调整你的加载项或宏以与共同创作流畅集成。

共同创作是向所有 Excel Online 用户提供的功能。 此功能也向 Excel for Windows Desktop 提供,但仅面向 Office 365 客户。

共同创作简介

共同创作允许你与其他用户同时编辑托管在云中的工作簿(即 OneDrive、OneDrive for Business 或 SharePoint Online)。 每次保存后,在该时间编辑该工作簿的所有人都可以看到此更改。 启用自动保存后,可以实时查看每个人对工作簿所做的更改。 如果你还没准备好让其他人查看你的更改,可以关闭自动保存,直到你准备好共享你的更改并接收其他人所做的更改为止。

共同创作原则

Excel 将自动同步对工作簿所做的更改(无论此更改是通过用户还是通过你的代码完成的)。 例如,假设代码在用户的实例上运行并修改了一个单元格的内容,如下所示:Range("A1").Value = "myNewValue"。 Excel 将负责将此更改发送给其他共同创作者。

现在,假设在另一个用户的实例上运行检查该单元格的内容的代码,如下所示:MsgBox Range("A1").Value。 第二个用户将看到已由第一个用户设置的值 "myNewValue"

但是,Excel 不会自动同步由你的代码在工作簿内容外部创建的任何变量。 例如,假设你的代码读取单元格中的值,然后将其加载到变量:

Dim myVariable
myVariable = Range("A1").Value

Excel 不会自动更新 myVariable 的值,这意味着 myVariable 不会与由在其他共同创作者的 Excel 实例上运行的代码所创建的同一名称的变量同步。

可能需要调整你的解决方案以适应共同创作环境的情况

因为现有加载项和宏可以依赖 Excel 将它们对工作簿所做的更改无缝传输到共同创作者,所以,通常可以在此新环境中使用你的代码,而不进行任何更改或更新。 但是,在两种情况下,如果你希望你的代码能够在共同创作设置中顺利工作,可能需要调整你的代码:

添加了 BeforeRemoteChangeAfterRemoteChange 事件,使你能够在适用的情况下管理远程更改。

在工作簿内容外部具有内部、内存中状态的加载项

假设有一个加载项,该加载项允许用户基于 Excel 工作簿中的数据创建自定义图表。 此加载项将用户的图表数据加载到工作簿中的一个隐藏工作表。 当用户打开包含自定义图表的文件时,加载项将读取隐藏的工作表上的数据并将该图表加载到内存中。 当用户编辑该图表时,此内存中结构将进行更新,并在每次保存前重新写入到文件中。 此加载项假定唯一一次需要读取隐藏的工作表并将其加载到内存的时间是在打开文件时。

共同创作实现了另一种可能性:隐藏的工作表可同时由运行同一加载项的另一个用户修改。 如果出现这种情况,则用户正在查看的图表可能不会同步。例如:

  • 假设用户 A 打开文件并开始查看现有自定义图表。
  • 在她执行此操作时,用户 B 打开了同一文件并开始对自定义图表进行更改(例如,更改图表的类型)。
  • 该更改将由用户 B 的计算机上的加载项保存到工作表,但用户 A 从不会看到这一更改,除非她重新加载该文件。

解决方法

尽可能避免进行有关何时能够更改工作簿数据的假设。 在本例中,可以修改加载项以响应 AfterRemoteChange 事件,然后查看隐藏的工作表的值,以确定其是否需要由加载项再次读取,以允许用户 A 查看用户 B 对图表所做的更改。 每当图表范围更改时,即运行加载项。 此操作在加载时进行,并可在远程更改时进行。 因此,AfterRemoteChange 中的逻辑应重新运行加载项。

利用事件的加载项

你的加载项或宏可能已订阅保存或更改事件。 随着共同创作的引入,可能会遇到以下问题:

保存事件

当你的代码使用 BeforeSaveAfterSave 等保存事件时,可能会遇到问题。 有关详细信息,请参阅保存事件和自动保存的潜在问题

更改事件

默认情况下,你的代码通常无需处理来自远程用户的更改。 但是,在某些情况下,处理远程更改可能会导致问题。 这里将探讨两个示例方案。

示例方案:数据验证

当在工作簿中编辑特定范围时,将触发更改事件。 然后,你的加载项代码将验证此更改,如果检查失败,将通过弹出窗口通知用户。 但是,如果在该工作簿上进行协作的所有远程用户都收到有关与自己的更改不相关的验证失败的通知,这可能会导致不好的使用体验。

示例

在此示例中,创建了一个图表,该图表显示出售各种甜品的销售额。 出售的商品的成本和数量都不应为负数,所以会进行验证检查,该检查会向用户显示一条消息。 将无效值推送到远程用户时,不应向其显示验证消息。

Public Sub ValidateFigures()
    Dim rangeToValidate As Range
    Set rangeToValidate = ActiveWorkbook.Worksheets("Chart").Range("B2:C6")
    For Each cell In rangeToValidate.Cells
        If (cell.Value < 0) Then
            MsgBox ("Error: Value should not be negative. " & cell.Address)
        End If
    Next
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    ActiveWorkbook.Worksheets("Chart").ValidateFigures
End Sub

因此,在这种情况下,无需订阅 BeforeRemoteChangeAfterRemoteChange 事件。

Private Sub Workbook_AfterRemoteChange()
    ' Do not call validation from RemoteChange event
    'ActiveWorkbook.Worksheets("Chart").ValidateFigures
End Sub

图 1. 表示甜点销售的图表示例

甜品销售额

示例方案:数据一致性

触发更改事件,且你的加载项代码将工作簿中的数据与工作簿的另一个部分或外部系统中的数据同步。 如果远程用户接收了导致加载项代码同步同一数据的更改,这可能会导致远程用户的使用体验降低或导致外部系统中的数据重复。

更改事件中的潜在问题

虽然通常你不希望你的事件处理程序代码根据来自远程用户的更改运行,但是触发更改事件的行为可能会导致问题。 以下是问题的一些示例以及如何使用 BeforeRemoteChangeAfterRemoteChange 事件来解决这些问题。

示例方案:数据可视化

你的加载项根据在工作簿中的范围中找到的位置数据来绘制数据点。 如果用户编辑任何位置数据,则所有远程用户都应接收此更改,以更新每个用户的地图。

示例

假设你已创建了一个自定义地图。 在此示例中,可以添加代码以更改位置数据,然后更新该地图。 此工作簿是与其他城市中的某人共享的。 启用自动保存后,更改将被传递给远程用户,但该用户的地图将不会更新。

Public Sub UpdateMap()
    'Code that updates map
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    'Call subroutine that updates map
End Sub

现在使用 AfterRemoteChange 事件添加更新该地图的代码。 发送给远程用户的后续更改将用于更新该地图。

Private Sub Workbook_AfterRemoteChange()
    'Call subroutine that updates map
End Sub

图 2. 具有几个兴趣点的伦敦地图示例

伦敦位置

示例方案:导航任务窗格

你的加载项在任务窗格中显示所有当前工作簿选项卡,以便于导航。 如果用户添加了一个工作表,则所有远程用户都应接收此更改,以便每个用户的任务窗格都可以显示指向新工作表的链接。

另请参阅

支持和反馈

有关于 Office VBA 或本文档的疑问或反馈? 请参阅 Office VBA 支持和反馈,获取有关如何接收支持和提供反馈的指南。