【问题标题】:VBA - Unable to map drive to sharepoint on another computerVBA - 无法将驱动器映射到另一台计算机上的共享点
【发布时间】:2017-11-30 15:26:53
【问题描述】:

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

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

但是,当我在同事的计算机(Window 7)上运行包含相同代码的同一个 Excel 工作簿时,它失败了。没有显示错误,只是它一直在加载和加载,直到 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

【问题讨论】:

  • 每个版本都在运行哪些 Excel 版本(一个可以运行,一个不运行)?您知道系统在这 4 个过程中的哪个过程中变得无响应吗?
  • @ashleedawg 嗨,对不起,忘了提到 excel 的版本。已经更新了问题。所有人都在使用 Excel 2016。系统在获得可用驱动器后变得无响应。
  • 您的代码示例中也缺少程序 AddReference(仅当您确定它是导致挂起的这些程序之一时才相关)
  • @ashleedawg 是的。我删除了那部分,因为我担心代码太长。我确实检查了工具-> 参考。这是正确的。既然你提到了,我还是会补充的。

标签: vba excel sharepoint connection


【解决方案1】:

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

我运行了imgClicked(假设这是您开始的程序),有人告诉我,两次"Next available letter = Z""Hello",然后 Excel 崩溃了(可能卡在一个循环中)创建 FileSystem 对象以查找可用的驱动器号?)

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

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

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

问题是否解决还有一件事:

在模块的开头添加Option Explicit,然后在项目中添加Compile,并修复缺少的变量声明。

在对问题进行故障排除时建议使用此方法,以消除变量声明问题的可能原因。

【讨论】:

  • 感谢您的回答,但工作的(我的)确实显示了"Next available letter = Z""Hello" 两次并且没有崩溃。不工作的显示"Next available letter = Z""Hello" Once 并崩溃。
  • 好的,仍然添加那行代码来消除这个问题。你知道如何?如果机器具有不同的 RAM 和 CPU,那么使用相同代码的机器更有可能崩溃。另外,当它变得无响应时,您将如何结束它?您是否尝试过重新启动问题机器并查看问题是否仍然存在?对象问题可能会导致内存泄漏,并且强制应用程序退出可能会导致多个实例保留在后台。我曾经发现在后台运行了 25 个 Outlook 副本,每次运行一个子时都会运行一次,因为我忘记了 Set _Object_ = Nothing :-)
  • 感谢分享。 Option Explicit 帮助我找到变量的错字(变量与问题无关)并解释 RAM 和 CU。当我的同事有空(他现在正在使用电脑)时,我会尝试你的建议。
  • ...我相信在MapDrive 中缺少objNetwork 的对象声明?
  • ...需要Dim objNetwork as Object(参见msdn.microsoft.com/en-us/vba/language-reference-vba/articles/…)...可能不是问题,但无论如何都应该在代码的两个副本上修复,尤其是在诊断无响应时(因为它可能是由通过内存问题)。只需将Option Explicit 留在那里(项目中的所有模块)并重复编译,直到您没有收到任何警告。
猜你喜欢
  • 2011-10-14
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多