简体   繁体   English

从 Outlook 打开 Excel 文件时出错:由多个用户。 自动化

[英]Error when opening excel file from outlook: by multiple user. Automation

I have a macro in Outlook 2010. It checks if a file is opened by another user, if not then open it, fill it up with data, save it and close it.我在 Outlook 2010 中有一个宏。它检查文件是否被另一个用户打开,如果没有,则打开它,用数据填充它,保存并关闭它。

When the users use it at the same time, the faster pc seems to win, and the other user is locked out, thus resulting in a error and even freezes Outlook.当用户同时使用时,速度较快的电脑似乎胜出,其他用户被锁定,从而导致错误甚至冻结Outlook。

First I tried unprotected workbooks, so everyone can use the macros at the same time (I didn't do the isworkbookopen function then), but it resulted in an automation error:首先我尝试了不受保护的工作簿,这样每个人都可以同时使用宏(当时我没有做 isworkbookopen 函数),但它导致了自动化错误:

Run-time error '-2147418111 (80010001)':运行时错误“-2147418111 (80010001)”:

Automation error自动化错误

Call was rejected by callee when debugged, it highlighted the wb.open strpath part调试时调用被被调用者拒绝,它突出显示了 wb.open strpath 部分

Here is a part of my code now:这是我现在代码的一部分:

Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliSeconds As Long)

Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long

On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0

Select Case ErrNo
Case 0:    IsWorkBookOpen = False
Case 70:   IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function


Public Sub test()
Sleep 1000
End Sub


Sub Sample()

Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Excel.Worksheet

Dim xlApp2 As Object
Dim xlWB2 As Object
Dim xlSheet2 As Excel.Worksheet

Const strpath As String = "P:\Head\....xls"
Const strpath2 As String = "P:\Head\....xls"
Dim Ret
Dim Ret2

Z = 0

0:
Ret = IsWorkBookOpen(strpath) 'the path of the workbook
Ret2 = IsWorkBookOpen(strpath2)

If Ret = False Then
GoTo masodikif
Else
GoTo elseag
masodikif:
    If Ret2 = False Then
    GoTo ifvege
    Else
    GoTo elseag

elseag:     Call test
         Z = Z + 1
        If Z = 50 Then
        MsgBox "Please try again in a few second!"            
        End
        Exit Sub
        End If
        GoTo 0:

        End If
        End If

ifvege:


If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
    Application.StatusBar = "Please wait while Excel source is opened ... "
    Set xlApp = CreateObject("Excel.Application")
    bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.workbooks.Open(strpath)
Set xlSheet = xlWB.sheets("Munka1")



If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
On Error Resume Next
Set xlApp2 = GetObject(, "Excel.Application")
If Err <> 0 Then
    Application.StatusBar = "Please wait while Excel source is opened ... "
    Set xlApp2 = CreateObject("Excel.Application")
    bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB2 = xlApp2.workbooks.Open(strpath2)
Set xlSheet2 = xlWB2.sheets("Munka1")

A lot of code again又是一大堆代码

xlWB2.Save
xlWB2.Close savechanges:=True

xlWB.Save
xlWB.Close savechanges:=True


Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing

Set xlApp2 = Nothing
Set xlWB2 = Nothing
Set xlSheet2 = Nothing

I think using the vba primitives to check to see if the workbook is open is the wrong approach here.我认为使用 vba 原语检查工作簿是否打开是错误的方法。 I can respect that you're trying to write reusable subs as well, but in this case I think they needlessly complicate your code.我也可以尊重您正在尝试编写可重用的子程序,但在这种情况下,我认为它们不必要地使您的代码复杂化。 If I were doing something like this, here is how I would approach it.如果我正在做这样的事情,这就是我将如何处理它。

Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliSeconds As Long)

Public Sub Sample()
    'I avoid using late binding.  If this is VBS, you'll have to, but if it is in Outlook, I'd set the references.
    Dim xlApp As Excel.Application
    Dim xlWB as Excel.Workbook
    Dim xlSheet As Excel.Worksheet
    '... follow the example for the rest of the dims
    Const strpath as string = "P:\Head\....xls"
    Const strpath as string = "P:\Head\....xls"
    Dim Z as integer
    Z = 0
    Set xlApp = New Excel.Application
    Set xlWB = xlApp.Workbooks.Open(strPath)
    Do until Z = 50 or xlWB.ReadOnly = False
        xlWB.Close
        Set xlWB = Nothing
        Sleep(1000)
        Set xlWB = xlApp.Workbooks.Open(strPath)
        Z = Z + 1
    Loop
    If Z = 50 and xlWB.ReadOnly = True then
        MsgBox "Please try again in a few seconds!"
        End
    End If
    'If we've made it here, we have read write access to the workbook
    'Do stuff... 

I didn't write out all the code to check both workbooks, but you should get the general idea of how to handle it from here.我没有写出检查两个工作簿的所有代码,但您应该从这里获得如何处理它的一般概念。 Not that your approach is wrong outside of using the vba primitives to check to see if the workbook is open, but I think this would be much cleaner and easier to troubleshoot.并不是说除了使用 vba 原语检查工作簿是否打开之外,您的方法是错误的,但我认为这会更清晰,更容易进行故障排除。 I'd recommend you try adapting your code to follow this example.我建议您尝试调整代码以遵循此示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM