【问题标题】:Open & Check out Excel workbook from SharePoint从 SharePoint 打开并签出 Excel 工作簿
【发布时间】:2019-10-21 09:22:36
【问题描述】:

我正在尝试将数据写入到我们的 SharePoint 文档库中托管的 Excel 工作簿中。
我从 Microsoft Project 实例化 Excel。

我尝试了以下方法:

  1. 检查文件是否可以签出
  2. 如果可以签出就打开

这里是sn-p的代码:

If ExcelApp.Workbooks.CanCheckOut (FileURL) = True Then
    Set NewBook = ExcelApp.Workbooks.Open(FileName:=FileURL, ReadOnly:=False)
    ExcelApp.Workbooks.CheckOut (FileURL)
Else
    MsgBox "File is checked out in another session."
End If

CanCheckOut 函数总是返回 FALSE。我无法判断 Excel 实例何时可以签出文件。
是不是因为我从 MS Project 调用 VBA 代码而无法工作?

我的应用应该能够检查文件是否未签出,然后签出、更新并保存并重新签入。

【问题讨论】:

  • 如果您共享您正在使用的 Excel / SharePoint 版本,将会有所帮助。但无论如何,在 FileUrl 参数中,尝试 ThisWorkbook.FullNameURLEncoded 。根据我的经验,VBA 功能不是很可靠,您必须通过变通方法完成工作。

标签: excel vba sharepoint sharepointdocumentlibrary


【解决方案1】:

我通过反复试验发现,Workbooks.CanCheckOut (Filename:= FullName) 其中 FullName 是 SharePoint 文件的 URL,仅适用于未在当前 Excel 实例中打开的文件。

如果您在当前 Excel 实例中打开了文件,该方法将始终返回 False,这显然是这里的情况。 Workbooks.CheckOut (ActiveWorkbook.FullName) 打开文件,将其签出,然后莫名其妙地关闭文件。因此,打开和签出 SharePoint 文件只需 3 个步骤。

Sub CheckOutAndOpen()
Dim TestFile As String

TestFile = "http://spserver/document/Test.xlsb"
If Workbooks.CanCheckOut(TestFile) = True Then
    Workbooks.CheckOut(TestFile)
    Workbooks.Open (TestFile)
Else
    MsgBox TestFile & " can't be checked out at this time.", vbInformation
End If
End Sub

这有点违反直觉,因为在手动处理 SharePoint 文件时,您必须打开它们以查看它们是否可以被签出,然后执行签出操作。 MSDN 或 Excel VBA 都没有提到如果您在当前 Excel 实例中打开文件,Workbooks.CanCheckOut (Filename:= FullName) 方法总是返回 False。

【讨论】:

  • 我没有在当前 Excel 实例中打开文件。我打开了一个 Microsoft Project 文件,它启动了一个 Excel 实例,然后尝试打开并签出工作簿。
【解决方案2】:

其他方法对我没有用。这将检查文件并隐藏打开它并终止(可见 = False),或者您可以打开它(可见 = True)并删除退出,但是当文档被签出时,我似乎无法定位或进一步检查该 mXLApp 文档。解决方案是不要让 mXLApp 文档保持打开状态,但一旦关闭就可以正常打开同一个文档,然后它将使用 Check in 代码行进行 Check in。

Sub TestCheckOut()
    Dim FileName as String 
    FileName  = "http://spserver/document/Test.xlsx"

    SP_CheckOut FileName
End Sub

Sub SP_CheckOut(docCheckOut As String)
    Set mXlApp = CreateObject("Excel.Application")
    ' Determine if workbook can be checked out.
    ' CanCheckOut does not actually mean the doc is not currently checked out, but that the doc can be checked in/out.
    If mXlApp.Workbooks.CanCheckOut(docCheckOut) = True Then
        mXlApp.Workbooks.Open fileName:=docCheckOut
        mXlApp.Workbooks.CheckOut docCheckOut
        ' False is hidden
        mXlApp.Visible = False
        mXlApp.Quit
        Set mXlApp = Nothing
        
        Workbooks.Open fileName:=docCheckOut

    Else
        MsgBox "Unable to check out this document at this time."
    End If
End Sub  

至于Checkin,除了:

Workbooks(CheckName).checkin SaveChanges:=True, Comments:=""

Sub CheckIn(CheckName As String, CheckPath As String)
' Must be open to save and then checkin
    Dim wb As Workbook
    On Error Resume Next
    Set wb = Workbooks(CheckName)
    If Err = 0 Then
        WorkbookIsOpen = True
    Else
        WorkbookIsOpen = False
        
        Set wb = Workbooks.Open(CheckPath)
    End If

    wb.CheckIn SaveChanges:=True, Comments:=""

End Sub

我确实尝试在 SharePoint 浏览器链接上使用查询来确定谁签出了文档(如果有人)。这有时奏效。如果它确实有效,一半的时间会花费很长时间才能发挥作用,而另一半的时间会抛出超时错误。更不用说查询会破坏其他过程,例如保存或某些其他宏。所以我整理了一个 WebScrape,它可以快速返回谁可能已经检查了文档。

Sub TestWho()
    Dim SPFilePath As String  

    SPFilePath = "http://teams.MyCompany.com/sites/PATH/PATH/Fulfillment/Forms/AllItems.aspx"

    Debug.Print CheckedByWho(SPFilePath , "YOURdocName.xlsx")
End Sub

Function CheckedByWho(ShareFilePath As String, ShareFileName As String)
    Dim ie As Object
    Dim CheckedWho As String
    Dim ImgTag As String
    Dim CheckStart, CheckEnd As Integer
    Dim SplitArray() As String
    
    Set ie = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")

    With ie
        .Visible = False
        .Navigate ShareFilePath
        Do Until .readyState = 4: DoEvents: Loop
        Do While .Busy: DoEvents: Loop
    End With

    CheckedWho = "Not Check Out"

    For Each objLink In ie.document.getElementsByTagName("img")
        ImgTag = objLink.outerHTML

        CheckedOutPos = InStr(objLink.outerHTML, ShareFileName & "
Checked Out To:")
        If CheckedOutPos > 0 Then
            CheckStart = InStr(objLink.outerHTML, "Checked Out To: ")
            CheckedWho = Mid(objLink.outerHTML, CheckedOutPos + 41)

            SplitArray = Split(CheckedWho, """")
            CheckedWho = SplitArray(0)
       End If

    Next objLink

    CheckedByWho = CheckedWho

    ie.Quit
End Function 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 2015-06-02
    相关资源
    最近更新 更多