VBA - 无法将驱动器映射到另一台计算机上的共享点

VBA - Unable to map drive to sharepoint on another computer

我正在使用 VBA 映射到公司的共享点驱动器。目的是将本地文件保存到sharepoint,成功后删除本地文件并取消映射驱动器。

在我的机器上(Windows 10 64 位),代码运行良好,成功映射驱动器,创建文件夹和文件,成功上传到共享点并取消映射驱动器。

但是,当我 运行 包含相同代码的同一个 excel 工作簿在我同事的计算机 (Window 7) 上时,它失败了。没有显示任何错误,只是它一直在加载和加载直到 Excel Not Responsive。我尝试手动映射驱动器,它成功了。

我尝试调试并发现代码在 MsgBox "Hello" 停止(继续加载)但无法弄清楚缺少什么。

两者都在使用 Excel 2016

感谢任何帮助和建议。让我知道是否需要更多信息。提前致谢。

这是我的vba代码

Sub imgClicked()

Dim fileName As String

Dim SharePointLib As String
Dim MyPath As String
Dim folderPath As String
Dim objNet As Object
Dim copyPath As String
Dim copyFilePath As String

folderPath = Application.ThisWorkbook.path
MyPath = Application.ThisWorkbook.FullName

Dim objFSO As Object
Dim strMappedDriveLetter As String
Dim strPath As String
Dim spPath As String

strPath = "https://company.com/sites/test/test 123/" 'example path
spPath = AvailableDriveLetter + ":\test.xlsm" 'example path
copyPath = folderPath + "\copyPath\"

'Add reference if missing
Call AddReference

Set objFSO = CreateObject("Scripting.FileSystemObject")

With objFSO

strMappedDriveLetter = IsAlreadyMapped(.GetParentFolderName(strPath))

If Not Len(strMappedDriveLetter) > 0 Then

  strMappedDriveLetter = AvailableDriveLetter

  If Not MapDrive(strMappedDriveLetter, .GetParentFolderName(strPath)) Then

    MsgBox "Failed to map SharePoint directory", vbInformation, "Drive Mapping Failure"
     Exit Sub

  End If

 End If

 ' Check file/folder path If statement here

End With

Set objFSO = Nothing

End Sub

获取可用驱动器的代码

  ' Returns the available drive letter starting from Z
 Public Function AvailableDriveLetter() As String

' Returns the last available (unmapped) drive letter, working backwards from Z:

Dim objFSO As Object
Dim i As Long

Set objFSO = CreateObject("Scripting.FileSystemObject")

For i = Asc("Z") To Asc("A") Step -1

Select Case objFSO.DriveExists(Chr(i))

  Case True

  Case False

    Select Case Chr(i)

      Case "C", "D"     ' Not actually necessary - .DriveExists should return True anyway...

      Case Else

        AvailableDriveLetter = Chr(i)

        Exit For

    End Select

End Select

Next i

Set objFSO = Nothing
 MsgBox "This is the next available drive: " + AvailableDriveLetter ' returns Z drive
 MsgBox "Hello" ' After this msgBox, starts loading until Not Responsive
End Function

映射驱动器的函数

Public Function MapDrive(strDriveLetter As String, strDrivePath As String) As Boolean

Dim objNetwork As Object

If Len(IsAlreadyMapped(strDrivePath)) > 0 Then Exit Function

Set objNetwork = CreateObject("WScript.Network")

objNetwork.MapNetworkDrive strDriveLetter & ":", strDrivePath, False

MapDrive = True
MsgBox "Successfully Created the Drive!"
Set objNetwork = Nothing

End Function

MappedDrive 代码

Public Function GetMappedDrives() As Variant

' Returns a 2-D array of (1) drive letters and (2) network paths of all mapped drives on the users machine

Dim objFSO As Object
Dim objDrive As Object
Dim arrMappedDrives() As Variant
Dim i As Long

Set objFSO = CreateObject("Scripting.FileSystemObject")

ReDim arrMappedDrives(1 To 2, 1 To 1)

For i = Asc("A") To Asc("Z")

If objFSO.DriveExists(Chr(i)) Then

  Set objDrive = objFSO.GetDrive(Chr(i))

  If Not IsEmpty(arrMappedDrives(1, UBound(arrMappedDrives, 2))) Then

    ReDim Preserve arrMappedDrives(1 To 2, 1 To UBound(arrMappedDrives, 2) + 1)

  End If

  arrMappedDrives(1, UBound(arrMappedDrives, 2)) = Chr(i)            ' Could also use objDrive.DriveLetter...
  arrMappedDrives(2, UBound(arrMappedDrives, 2)) = objDrive.ShareName
End If

Next i

GetMappedDrives = arrMappedDrives

Set objDrive = Nothing
Set objFSO = Nothing

End Function

Public Function IsAlreadyMapped(strPath As String) As String

' Tests if a given network path is already mapped on the users machine
' (Returns corresponding drive letter or ZLS if not found)

Dim strMappedDrives() As Variant
Dim i As Long

strMappedDrives = GetMappedDrives

 For i = LBound(strMappedDrives, 2) To UBound(strMappedDrives, 2)

  If LCase(strMappedDrives(2, i)) Like LCase(strPath) Then

  IsAlreadyMapped = strMappedDrives(1, i)

    Exit For

  End If

  Next i

  Set objNetwork = Nothing

  End Function

添加引用

Sub AddReference()
 'Macro purpose:  To add a reference to the project using the GUID for the
 'reference library

Dim strGUID As String, theRef As Variant, i As Long

 'Update the GUID you need below.
strGUID = "{420B2830-E718-11CF-893D-00A0C9054228}"

 'Set to continue in case of error
On Error Resume Next

 'Remove any missing references
For i = ThisWorkbook.VBProject.References.Count To 1 Step -1
    Set theRef = ThisWorkbook.VBProject.References.Item(i)
    If theRef.isbroken = True Then
        ThisWorkbook.VBProject.References.Remove theRef
    End If
Next i

 'Clear any errors so that error trapping for GUID additions can be evaluated
Err.Clear

 'Add the reference
ThisWorkbook.VBProject.References.AddFromGuid _
GUID:=strGUID, Major:=1, Minor:=0

 'If an error was encountered, inform the user
Select Case Err.Number
Case Is = 32813
     'Reference already in use.  No action necessary
Case Is = vbNullString
     'Reference added without issue
Case Else
     'An unknown error was encountered, so alert the user
    MsgBox "A problem was encountered trying to" & vbNewLine _
    & "add or remove a reference in this file" & vbNewLine & "Please check the " _
    & "references in your VBA project!", vbCritical + vbOKOnly, "Error!"
End Select
On Error GoTo 0
End Sub

过程 imgClicked 正在多次调用函数 AvailableDriveLetter。请记住,该函数必须在您每次引用它时执行。

我 运行 imgClicked(假设这是你开始的程序)我被告知,两次"Next available letter = Z""Hello" 然后它崩溃了 Excel(可能陷入了创建 FileSystem 对象以查找可用驱动器号的循环中?)

尝试在过程开始时将 AvailableDriveLetter 分配给一个变量(字符串),并在每次需要该值时引用该变量,看看问题是否仍然存在。

(记得在执行前保存——在解决“应用程序挂起”问题时我很沮丧,因为我总是忘记保存我的更改,然后在崩溃时丢失它们!)

如果这不起作用,请在“Hello”框后的 End Function 行中添加一个断点 (F9),然后查看代码是否停在那里。 (我很难相信 MsgBoxEnd Function 是罪魁祸首。)如果不是,那之后运行哪个过程?

关于问题是否解决还有一点:

Add Option Explicit at the very beginning of your module and then Compile the project and fix your missing variable declaration(s).

This is recommended whenever troubleshooting an issue as a means to eliminate variable declaration issues as a possible cause.