【问题标题】:Update an excel file by multiple users at same time without opening the file多个用户同时更新一个excel文件而不打开文件
【发布时间】:2018-12-16 16:28:33
【问题描述】:

场景

我有一个包含数据的 excel 文件。有多个用户同时访问该文件。

问题

由于一次只允许一个用户打开该文件,如果多个用户尝试同时向该excel文件输入数据会出现问题

问题

有什么方法可以在不打开它的情况下更新 excel 文件(例如:向单元格添加值、从单元格中删除值、查找特定单元格等),以便多个用户可以同时更新它用excel VBA的时间?

【问题讨论】:

  • 根据这篇文章,您仍然可以使用旧的“共享工作簿”功能。我能够为 2016 工作簿启用它。 presentationpoint.com/blog/multiple-users-excel-2016-datasheet
  • 文件现在可以在启用旧共享选项后由不同用户同时更新。让我尝试一些 VBA 代码来更新文件,看看它是否也有效。谢谢@DeanOC
  • 不确定谁对问题投了反对票,但没有提及投反对票的原因。
  • @DeanOC 共享工作正常。但是现在这个问题是我打开共享的那一刻,VBA 似乎被禁用了。我不能再打开宏了。所以我仍然需要找到一种方法来更新单元格而不打开它。
  • 我以为您只是将 VBA 用作模拟多个用户的解决方法,但听起来您希望让用户在编辑文档的同时让代码修改文件。抱歉,无法为您提供帮助。

标签: vba excel


【解决方案1】:

我去了使用共享文件的方向。但是后来发现是excel共享的文件有很多bug。如果使用共享文件,excel/宏可能会非常慢,间歇性崩溃,有时整个文件可能会损坏,之后无法打开或修复。还取决于有多少用户使用该文件,文件大小会变得相当大。所以最好不要使用共享工作簿。完全不值得尝试。相反,如果需要多个用户同时更新数据,最好使用一些数据库,例如MSAccess,MSSql(Update MSSQL from Excel)等与excel。对于我的情况,由于用户数量较少,我没有使用任何数据库,而是提示用户等到其他用户关闭该文件。请查看以下代码以检查文件是否已打开,如果已打开,则提示用户。我从堆栈溢出本身获得了这段代码,并根据我的需要进行了修改。

如下调用模块TestFileOpened

Sub fileCheck()
  Call TestFileOpened(plannerFilePathTemp)
    If fileInUse = True Then
        Application.ScreenUpdating = True
        Exit Sub
    End If
End Sub

这里的plannerFilePathTemp 是原始文件的临时文件位置。每当打开一个 excel 文件时,都会创建一个临时文件。例如,您的原始文件位置如下

plannerFilePath = "C:\TEMP\XXX\xxx.xlsx"

因此您的临时文件位置将是

plannerFilePathTemp = "C:\TEMP\XXX\~$xxx.xlsx"

或者换句话说,临时文件名将是~$xxx.xlsx

Call TestFileOpened(plannerFilePathTemp)会调用以下代码

Public fileInUse As Boolean
Sub TestFileOpened(fileOpenedOrNot As String)
Dim Folder As String
Dim FName As String

Set objFSO = CreateObject("Scripting.FileSystemObject")

If objFSO.FileExists(fileOpenedOrNot) Then
    fileInUse = True
    MsgBox "Database is opened and using by " & GetFileOwner(fileOpenedOrNot) & ". Please wait a few second and click again", vbInformation, "Database in Use"
Else
    fileInUse = False
End If

End Sub

Function GetFileOwner(strFileName)
    Set objWMIService = GetObject("winmgmts:")
    Set objFileSecuritySettings = _
    objWMIService.Get("Win32_LogicalFileSecuritySetting='" & strFileName & "'")
    intRetVal = objFileSecuritySettings.GetSecurityDescriptor(objSD)

    If intRetVal = 0 Then
       GetFileOwner = objSD.Owner.Name
    Else
       GetFileOwner = "Unknown"
    End If
End Function

我在使用共享文件时也遇到了内存不足的问题。所以在这个过程中,我想出了以下方法来最小化内存消耗

Some tips to clear memory

【讨论】:

  • 当我被强制尝试在电子表格中进行多用户输入时,我通常会让每个用户都有自己的日常工作簿,而经理有一个主文件可以复制当他们按下按钮时,所有信息都会结束。
  • @DarrenBartrup-Cook 这也是一个好方法。但就我的情况而言,它无法应用,因为有些东西迫使每个人都在一个文件而不是单独的文件中进行更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多