"Disconnected Network Drive" in My Computer - vba

We use VPN to connect to the work network. I have a mapped network drive that shows "Disconnected Network Drive" in My Computer immediately after I connect. While in this state I run a VBA routine:
Dim dr As String: dr = "F:\T\"
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(dr) Then
Call fso.CreateFolder(dr)
End If
Even though the folder actually does exist, fso thinks it doesn't so it tries to create the folder and throws an error: Run-time error 76: Path not found. Of course it can't find it because it is in a disconnected state. Any other operations using that network drive will fail too.
So I open My Computer and manually double-click the network drive. It connects just fine and I no longer get the error when running the code again. But this is problematic. I need a solution in the code to automatically connect the network drive.
Possible solution 1: Just use the UNC path instead of mapped drive letter. The problem with that is that I don't know what the path is. Nor do I want to use UNC; the code needs to be flexible to work with wherever the drive maps to. It's policy from the brass.
Possible solution 2: Re-map the network drive using Net Use or WshNetwork. Again, this isn't really possible as I don't know what the UNC path is or will be.
Possible solution 3: Connect using ShellExecute While this would work, it isn't really palatable as it opens a window to explore the folder (could use SW_HIDE to avoid showing the window, but then how would I close it?). Furthermore it doesn't connect instantly. I would need a delay of uncertain length to make this work. Not a good answer. MSDN ShellExecute Function
So is there a better solution? How do I connect the drive while waiting for it to return and throwing an error if not able to connect?
I need it to work for both VBScript and VBA.

Slugster's suggestion to get the mapped UNC value is a good one. Here is my solution as adapted from this answer This works for VBScript and VBA.
Sub testget()
Debug.Print getUNC("F:\T\")
End Sub
Function getUNC(dir)
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim sDrive: sDrive = fso.GetDriveName(dir)
Set fso = Nothing
Dim sMap: sMap = GetMappedDrive(sDrive)
If sMap <> "" And sDrive <> sMap Then
getUNC = Replace(dir, sDrive, sMap)
Else
getUNC = dir
End If
End Function
Function GetMappedDrive(sDrive)
Dim wshNetwork: Set wshNetwork = CreateObject("WScript.Network")
Dim oDrives: Set oDrives = wshNetwork.EnumNetworkDrives
Dim i
For i = 0 To oDrives.Count - 1 Step 2
If UCase(oDrives.Item(i)) = UCase(sDrive) Then
GetMappedDrive = oDrives.Item(i + 1)
Exit For
End If
Next
Set oDrives = Nothing
Set wshNetwork = Nothing
End Function

Related

Save output from process to Network Drive

We currently output to our SharePoint 2016 site which can be done via a URL option.
With the advent of SP Online, this is no longer possible, so we are going to output the file to a Network Drive and use MS Flow to push into SP Online.
The Access Database has a lot of processes in it which gather data from various places, calculates and then provides this output at the end.
I am not up to speed on all things VBA, but I cannot find a solution to being able to help me with this.
The current script for this is below, which also deletes the previous file to allow for the new one.
How would I go about updating this to output the file to a Network Drive - \\ServerName\Team\Reports\SP_Movement\Files_To_SP
Private Sub Update_ShP() 'Refreshes report in SharePoint Reports folder
'Code to delete report file from ShP
DoCmd.SetWarnings False
Dim xmlhttp
Dim sharepointUrl, sharepointFileName
Dim aFile, bFile As String
Dim LobjXML As Object
' Parent Sharepoint URL
sharepointUrl = "https://dms.company.com/Reports/"
' Sets the report name we want to remove (BoM Data 1)
aFile = "Q_ATP_OUTPUT.xlsx"
Set LobjXML = CreateObject("Microsoft.XMLHTTP")
sharepointFileName = sharepointUrl & aFile
' Removes the data from the server, false means synchronous
LobjXML.Open "DELETE", sharepointFileName, False
' Sends the request to remove the file
LobjXML.send
Set LobjXML = Nothing
DoCmd.RunSavedImportExport "Export-Q_ATP_OUTPUT"
DoCmd.SetWarnings True
End Sub
Thanks

Is there a VBA alternative to EnumNetworkDrives from Wscript.Network?

For several years we've been using code similar to the following (a result similar to that of net use) to convert UNC filenames to their legacy (drive letter) equivalents:
Dim network As Object: Set network = CreateObject("WScript.Network")
Dim netDrives As Object: Set netDrives = network.EnumNetworkDrives
Dim myLet As String
Dim myUnc As String
Dim i As Long
' loop through all network drives
For i = 0 To netDrives.count - 1 Step 2
myLet = netDrives.Item(i)
myUnc = netDrives.Item(i + 1)
myUnc = Replace(myUnc, "#SSL", "")
' hopefully we find it here
If InStr(LCase(uncname), LCase(myUnc)) Then
toLegacyName = myLet & Right(uncname, Len(uncname) - Len(myUnc))
Exit Function
End If
Next i
In the recent past, more login options (such as whether to use Citrix, VPN, or use the machine in the office) plus newer "file systems" (like Sharepoint) have rendered this code unreliable, where depending on how the user is signed on, network.EnumNetworkDrives may or may not return complete information. A drive may be present with Citrix but not using VPN, etc.
Are there other ways to do this? In the end, all we want to do is replicate net use.

Random File Selector?

It's been years since I've used Visual Basic. I downgraded from 2017 to 2010 (The version I was using while I was in school). I figured VB would be the best way to attempt a solution. (Although I'm sure there are other languages that would do it as well.)
I'm looking to get back into programming. Let me get to the problem.
My friend has an ever growing amount of text documents in a folder, and he wants a program to choose one at random, and open it.
I thought I'd put a TextBox with a Button that would let him open the folder where he stores his files. Then this program would read the number of text files in that folder, and randomly generate a number between one and that number, select, and open the document with its default program (if it's text, notepad; if it's DocX then word.)
I've been sitting at a blinking cursor for 45 minutes. I've gone on YouTube for help with this project.
Any advice, or help you guys can give me? Does this need to be simplified?
That sounds like a reasonable strategy to me.
It might be worth displaying some sort of progress to the user, say by putting the name of current file name being read into the status bar, in case there's a long delay reading the file names due to the large number of files in the folder, and/or a slow-running network drive. If you do this, remember to put a DoEvents into your loop to allow screen updates to display.
There's a separate thread on how to open files in their native handler here.
Hope this helps - good luck!
Option Explicit
Public oFSO As Object
Public arrFiles()
Public lngFiles As Long
Sub Main()
Dim sPath As String
sPath = InputBox("Enter folder path", "Folder path")
' clear starting point
lngFiles = 0
Erase arrFiles
Set oFSO = CreateObject("Scripting.FileSystemObject")
Call recurse(sPath)
Randomize
Dim lngRandomFileNumber As Long
lngRandomFileNumber = CLng(lngFiles * Rnd) + 1
MsgBox "This is random file, that will be opened: " & arrFiles(lngRandomFileNumber)
Call CreateObject("Shell.Application").Open(arrFiles(lngRandomFileNumber))
End Sub
Sub recurse(sPath As String)
Dim oFolder As Object
Dim oSubFolder As Object
Dim oFile As Object
Set oFolder = oFSO.GetFolder(sPath)
'Collect file information
For Each oFile In oFolder.Files
lngFiles = lngFiles + 1
ReDim Preserve arrFiles(lngFiles + 1)
arrFiles(lngFiles) = sPath & "\" & oFile.Name
Next oFile
'looking for all subfolders
For Each oSubFolder In oFolder.SubFolders
'recursive call
Call recurse(oSubFolder.path)
Next oSubFolder
End Sub
You can paste this code in any VBA supporting application (MS Access, MS Excel, MS Word), call VBA editor (Shift + F11) and paste this code. After that press F5 and select Main() function. You'll see prompt to enter folder path, and after that you would get random file path.
I think it should be understandable in practice to see what program do
Updated: #Belladonna mentioned it clearly, to open file in default program.
NB: This code is passes through subfolders also, if you want to exclude subfolders, you should comment the recursive call block in recurce function

Excel VBA to open Sharepoint folder and create list of hyperlinks for files within

Prior to being asked to migrate to SharePoint, I was using a collection of .xlsm files to set project teams up to manage projects. My Project Manager file included a macro that would go to a designated folder and create hyperlinks for all current project files. I've saved the collection of .xlsm files on SharePoint, but when I run the macro below (which I found here - Thank you!), I receive an error related to the "Set xFolder = xFSO.GetFolder(xPath)" line. Any help would be great. I've read several posting that may have the answer and tried several adjustments to the code, with no luck.
Sub Create_Hyperlinks_for_all_Current_Projects()
Range("B8:D38").Clear
MsgBox "Once you click OK, an explorer box will appear. Select the folder
containing all the CSTPs and then click OK again. HINT: The folder
containing all the CSTPs should be in the same folder this document was in
and should be called ''CSTPs''. Links to all CSTPs will then appear in the
white box on the Manager Menu."
Dim xFSO As Object
Dim xFolder As Object
Dim xFile As Object
Dim xFiDialog As FileDialog
Dim xPath As String
Dim I As Integer
Set xFiDialog = Application.FileDialog(msoFileDialogFolderPicker)
With xFiDialog
.InitialFileName = ThisWorkbook.Path
End With
If xFiDialog.Show = -1 Then
xPath = xFiDialog.SelectedItems(1)
End If
Set xFiDialog = Nothing
If xPath = "" Then Exit Sub
Set xFSO = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFSO.GetFolder(xPath)
For Each xFile In xFolder.Files
I = I + 2
ActiveSheet.Hyperlinks.Add Cells(I + 6, 2), xFile.Path, , , xFile.Name
Next
End Sub
I hope you find the following notes helpful.
They summarize the outcomes from several weeks of frustration.
If you are using SP365,
then the filesystemobject
no longer works very well, if at all.
I had hundreds of macros dependent on the FSO.
These have all worked great up until my organization migrated to SP365 :o(
Now they only work if I manually click
the Open Explorer button, in SP, first.
Opening Explorer provides Win Explorer with the required permissions to access SP.
This in turn provides the FSO with the required permissions to access SP.
But...in my case...FSO only works for a while.
For my first work around...
I rolled out a prototype app, which used a macro to automate
opening IE, opening Win Explorer and initializing permissions for the FSO
All worked great on my machine, for about an hour,
then some kind of timeout took me back to square one.
Colleagues on other machines experienced a range of FSO behaviours.
From all working ok. To having to rerun the connection macro every 30 seconds.
To nothing working at all.
I then invested time trying to update macros to connect to SP as a network drive.
Again, this is a process that I have used for years, up until migration to SP365.
Again, success connecting to SP365 seems to be very machine dependent.
In the end...with respect to my own requirements...
My work around was to create an SP view that lists all files.
Then use the Export to Excel option in SP to create an Excel data query.
Then copy the query into an Excel file that I refer to as Config.xlsx.
Then use Excel RefreshAll to update the list of files, each time a list is required.
Its not very elegant...but, it works ;o)
As I say....I hope this helps you / someone.
Feel free to connect on LinkedIn if you require any followup advice.
Peter,
LinkedIn name DrPeterEHSmee

Map Network Drive in Visual Basic 2010

I have spend months now trying to get the Visual Basic 2010 codes on how to map a network drive, disconnect them, and re-map network driver.
I will need to be able to map it to the profile folder to something like this:
Full path; “\10.10.10.12\Profile folder".
I need to log in to have access to the network folder /user:Domainname\UserName Password,
then confirm if mapping was successful with a message.
After the mapping I will request the profile name and check if such profile folder exists on the network.
If it exists, return a message stating that the profile exists, and delete the profile folder overwriting any folder property like if reading only, etc.
There are other tasks but his is where I am hit a dead end.
This question is old but maybe the OP is still looking. I wrote an HTA page awhile back to map a network address to a virtual drive. The code is VBScript and so uses the WScript library, which is not a native part of VB.net. See WScript in VB.Net on StackOverflow for more info on that.
The connect script:
SUB doLogOn()
Dim objNetwork, errNum, ojbFSO, strDrive, iNum
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists("\\MyServer\MyFolder\") = False Then
strDrive = "J:"
Set objNetwork = CreateObject("WScript.Network")
On Error Resume Next
objNetwork.MapNetworkDrive strDrive, "\\MyServer\MyFolder", False, "username", "password"
If Err.Number <> 0 Then
Err.Clear
End If
Set objFSO = Nothing
Set objNetwork = Nothing
End If
END SUB
Personally, I haven't found code to do the same thing in .Net. The VBScript shown above is pretty primitive; I hope it plus the info on binding WScript gives you an idea or two, though.
Edit: see Eric Dalnas' code, here