I want to move folders which are on network using Access VBA.
When I click button on form, it shall execute VBA code.
The below program moves local PC folders, when \\?\ is removed from the code. Using \\?\ before any network folder path, it is creating new folder on network.
When I want to move folders it is giving:
Run time Error 5 : Invalid Procedure call or Argument.
Upon debug , it highlights objF.MoveFolder oldStr, newStr
Private Sub btnBrowse_Click()
Dim oldStr As String
Dim newStr As String
Dim objF As Object
Me.OldPath = Me.FolderPath
Me.NewPath = GetFolder()
If Len(Me.NewPath) > 0 Then
Me.NewPath = "\\?\" & Me.NewPath
Me.FolderPath = Me.NewPath
Set objF = CreateObject("Scripting.FileSystemObject")
oldStr = Me.OldPath & "\*"
newStr = Me.NewPath & "\"
objF.MoveFolder oldStr, newStr
End If
End Sub
Use Microsoft.Scripting.Runtime file object to move folder.
We can't use these \\?\ paths. Should use conventional paths. \\?\ has noting to do with networks. Networks are \\servername\sharename\folder\file.ext
I removed \\?\ and it was working all good. \\?\ was creating confusion to MS Access in recognizing path, & thus was throwing error.
Related
I'm running into issues trying to pull info from files stored in Sharepoint.
Namely, FileExists isn't working and Overwrite file doesn't seem to be working either.
There was a discussion here, but few answers -> posting this question again in hopes some things have changed
My code runs like this:
strFileExists = Dir(Filepath & Filename)
And returns: File path not found -> I checked the path and even opened a file and recorded the macro to make sure it was the same file path without issue, but it appears DIR() is the issue.
The business dept I'm working with is entirely switching over to Sharepoint so hoping there's a straightforward solution without setting up network shares or doing C/personal/OneDrive things
You can navigate and look for files on OneDrive like this
Sub check_File_Exists()
Dim path As String
Dim strType As String
Dim file As Variant
Dim yourFile As String
'replace uname with your user name
path = "C:\Users\uname\OneDrive\"
strType = "*txt"
yourFile = "test.txt"
file = Dir(path & strType)
Do While (file <> "")
If file = yourFile Then
Debug.Print ("File: " & file & " found!")
Exit Do
End If
file = Dir
Loop
End Sub
Hope it helps
In my Access database, I have a button on a form to open an external file.
Here is the code that I am using for that.
Private Sub btn_OpenFile_Click()
Dim a As New Shell32.Shell
Dim strPath As String
strPath = Me.Attachment
strPath = Chr(34) & strPath & Chr(34)
Call a.ShellExecute(Me.Attachment)
'Call CreateObject("Shell.Application").ShellExecute(strPath)
'MsgBox strPath
End Sub
The problem that I have is if I actually put in the value of the variable (Me.Attachment) it works fine and opens the program and the file.
For Example, If I put in Call a.ShellExecute("C:\Docs\Some File.pdf") it will open. But if I use the variable in it's place it won't open and tells me it cannot find the file. I have verified with the msgbox that it is receiving the correct information. I have tried to wrap it in quotes and have used the Chr(34) as shown above but nothing works.
How can I get that variable to work in the ShellExcute command?
I have looked through all the forums and it seems like everyone is using a string but not a variable. I don't want to use just the shell command as I don't want to track down all of the different apps people use to open different types of files. There will be different file types that will need to be opened and I thought this would be easier than it actually is.
Thank you for the help.
I'm pretty sure that ShellExecute expects a Variant parameter, not a String.
So try this:
Call a.ShellExecute(CVar(strPath))
or use a Variant variable from the start.
I had the same problem here.
Both of the following work for me:
Dim a As New Shell32.Shell
Dim strPath As String
strPath = Me.Attachment
Call a.ShellExecute(strPath)
Dim a As Shell
Dim strPath As String
strPath = Me.Attachment
Set a = CreateObject("Shell.Application")
a.ShellExecute strPath
Even referencing Attachment directly.
a.ShellExecute(Me.Attachment)
This is a follow up to this question and great answer:
Copy files with progress bar
So I added the code from Siddharth Rout's answer and it does exactly what I want to happen with a minor exception. When I copy the files, I am looping through each file in the directory and copying it up as long as it is not *List.xml. Because I am replacing an existing library the 97% of the documents are pre-existing and I get prompted to replace existing documents each time.
Is there a way to get it to prompt me to choose to replace for all files? Do I need to reformat/structure the sequence of my code?
Function UploadToSharepoint(Folderpath As String, Foldername As String, Filenames() As String, SharepointLinks() As String) As Boolean
'upload file to sharepoint library based on the folder name
Dim SharePointLib As String
Dim LocalAddress As String
Dim DestinationAddress As String
Dim xCounter As Long
On Error GoTo loadFailed
Pickafolder:
Folderpath = FolderPick
Foldername = Left(Folderpath, Len(Folderpath) - 1)
Foldername = RIght(Foldername, Len(Foldername) - InStrRev(Foldername, "\"))
Select Case Foldername
Case "OPSS", "SSP", "OPSD", "MTOD", "SSD"
SharePointLib = "\\my.company.com\Subsite\" & Foldername & "\"
Case "West", "Eastern", "Northeastern", "Northwestern", "Head Office"
SharePointLib = "\\my.company.com\Subsite\NSP\" & Foldername & "\"
Case "NSP", "NSSP"
MsgBox "Pick the NSP regional sub folder: West, Eastern, Northeastern, Northwestern, Head Office"
GoTo Pickafolder
Case Else
MsgBox "Inappropriate directory to upload from. Please select one of the CPS download directories"
GoTo Pickafolder
End Select
Filenames = GetFilesDir(Folderpath)
ReDim SharepointLinks(LBound(Filenames) To UBound(Filenames))
For xCounter = LBound(Filenames) To UBound(Filenames)
LocalAddress = Folderpath & Filenames(xCounter)
DestinationAddress = SharePointLib & Filenames(xCounter)
'**********************************************************
Call VBCopyFolder(LocalAddress, DestinationAddress)
'**********************************************************
SharepointLinks(xCounter) = "#http:" & Replace(DestinationAddress, "\", "/") & "#"
Next xCounter
UploadToSharepoint = True
Exit Function
loadFailed:
UploadToSharepoint = False
End Function
And by the looks of things I am not excluding the file I was referring to earlier...must be doing that else where.
Update
Based on comment received at the linked question, the solution is to declare a public constant at the start:
Public Const FOF_NOCONFIRMATION As Long = &H10
and then in the copy procedure change the line of code to:
.fFlags = FOF_SIMPLEPROGRESS Or FOF_NOCONFIRMATION
Now, this does solve the problem of being constantly asked to confirm the replacement. I am very happy about this. The problem now is the progress window displays for the first file to be copied then disappears but fails to reappear for subsequent files. The remaining files still get copied and the prg carries on like it's supposed to. The whole point of the progress bar though was to let people know that "THINGS" were still happening in the background and now that is not happening. Is there something I need to adjust?
Update 2
After running my code and choosing a source directory on the network drive instead of the local computer, the copy window is popping up for every single file like I was expecting. I notice that sometimes the progress bar closes before reaching 100%. This leads me to believe that since the file sizes are so small that when it is copying from my local drive to sharepoint, the operation completes so fast that it does not have time to draw and update the progress window before its time to close it.
I have a database split in FrontEnd and BackEnd.
I have it running:
i) in my office
ii) updating/testing in my personal computer.
My BackEnd file is running in different Folder location according to computer running.
I want to place a code and check if file exist.
Code:
Sub FileExists()
Dim strPath As String '<== Office.
Dim strApplicationFolder As String
Dim strPathAdmin As String '<== Admin.
strPath = "\\iMac\Temp\"
strApplicationFolder = Application.CurrentProject.Path
strPathAdmin = strApplicationFolder & "\Temp\"
If Dir(strApplicationFolder & "SerialKey.txt") = "" Then
'===> Admin User.
If Dir(strPathAdmin & "*.*") = "" Then
'===> Empty Folder.
Else
'===> Files on folder.
End If
Else
'===> Office User.
If Dir(strPath & "*.*") = "" Then
'===> Empty Folder.
Else
'===> Files on folder.
End If
End If
End Sub()
I have this until now.
Any help.
Thank you...
Create a small function to check if a file exists and call it when needed.
Public Function FileExists(ByVal path_ As String) As Boolean
FileExists = (Len(Dir(path_)) > 0)
End Function
Since the backend database paths dont change, why dont you declare two constants and simply check their value?
Sub Exist()
Const workFolder As String = "C:\Work Folder\backend.accdb"
Const personalFolder As String = "D:\Personal Folder\backend.accdb"
If FileExists(workFolder) Then
'Work folder exists
End If
'....
If FileExists(personalFolder) Then
'Personal folder exists
End If
End Sub
This is a very belated reply, but don't reinvent the wheel. VBA can access the FileSystemObject, which includes a powerful set of methods that fetch file and folder information without requiring you to write your own functions, and the resulting code is much easier to read.
Second, borrowing on the previous answer, you know the folders you want the code to look at, and they don't change much, but because they could, I would also move your parameters into the declaration so they can be customized if needed or default to existing values.
Finally, FileExists is a verb, which should scream Function rather than Sub, so I'm guessing you want to return something and use it elsewhere in higher level code. It so happens that FileExists is already the name of a method in FileSystemObject, so I'm going to rename your function to LocatePath. You could return the valid path of the file you're looking for and decide by convention to quietly return an empty string "" if the target isn't found, and handle that in the calling procedure.
fs.BuildPath(strRootPath, strFileOrSubDir) appends strFileOrSubDir to strRootPath to construct a properly
formatted, full pathname and you don't need to worry about
whether you have backslashes (or too many) between the two.
It can be used to append files, or subdirectories, or
files in subdirectories.
fs.FileExists(strFullPath) is simple, returns True if strFullPath exists,
and False otherwise.
fs.GetFolder(strFolderName) returns a Folder object that has a
.Files property, which is a Collection object. Collection
objects in turn have a .Count property, which in this example
indicates how many files are in strFolderName. The Collection
object could also be used to iterate over all the files in the
folder individually.
What follows is your code refactored to incorporate all the changes I recommend according to what I think you're trying to achieve. It's not as symmetric as I'd like, but mirrors your code, and it's simple, easy to read, and finished in the sense that it does something.
Function LocatePath(Optional strWorkPath as String = "\\iMac",
Optional strHomePath as String = CurrentProject.Path,
Optional strFile as String = "SerialKey.txt"
Optional strSubDir as String = "Temp") as String
Dim fs as Object
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(fs.BuildPath(strHomePath, strFile)) Then
If fs.GetFolder(fs.BuildPath(strHomePath, strSubDir).Files.Count > 0 Then '===> Admin User.
LocatePath = fs.BuildPath(strHomePath, strFile)
ElseIf fs.GetFolder(fs.BuildPath(strWorkPath, strSubDir).Files.Count > 0 Then '===> Office User
LocatePath = fs.BuildPath(strWorkPath, strFile)
End If
Else 'Target conditions not found
LocatePath = ""
End If
Set fs = Nothing
End Function()
Ideally, I probably wouldn't specify strHomePath as String = CurrentProject.Path because strWorkPath as String = CurrentProject.Path is probably also true when you're at work, and you would want to do a better job of differentiating between the two environments. This is also what causes the little problem with symmetry that I mentioned.
I'm developing a MS Word macro which needs to open a file on a network drive and pass it the calling file's path as a parameter (i can then retrieve the parameters in the opened file using this method http://www.vbaexpress.com/forum/archive/index.php/t-21174.html).
What i am trying to achieve is the following:
1. Document X (any MS word document) calls document Y (macro document)
2. Document Y processes document X (using the Document object)
3. Document Y closes
The reason i am doing step 1 above is do that users don't have to deploy complex vba code (i am dealing with non IT literate users) and the ease of making updates and enhancements to the code if required.
The following code snippet opens the file with parameters:
Dim currentFilePath As String
currentFilePath = ThisDocument.Path & ThisDocument.Name
Dim MacroFilePath As String
MacroFilePath = ThisDocument.Path & "\Test.docm"
MacroFilePath = """" & MacroFilePath & """" & currentFilePath
Documents.Open (MacroFilePath)
The value of 'MacroFilePath' is gets setup like this (263 chars):
“\\XXXXXXXXXXXX\XX_XX\XXX_XXX XXXX procedural documentation\XX Design Support\Macros - DO NOT MOVE\Work in progress\Calling Document.docm” \\XXXXXXXXXXXX\XX_XX\XXX_XXX XXXX procedural documentation\XX Design Support\Macros - DO NOT MOVE\Work in progress\Test.docm
When I run the above code the error Run-Time '9105': String is longer than 255 characters occurs. I have tested the code where i moved the files to a shorter directory and it works. Is there a way to get around this or another way of achieving what i am trying to do?
Shorting the file paths by saving the documents elsewhere, changing the language i am programming in, or creating any kind of executable is not an option as i am in an enterprise environment.
X can open Y, then call a procedure in Y and pass in it's own path as a parameter.
You can use Application.Run to do this.
See:
https://msdn.microsoft.com/en-us/library/office/ff838935.aspx
Here's the example from that link:
Dim strTemplate As String
Dim strModule As String
Dim strMacro As String
Dim strParameter As String
strTemplate = InputBox("Enter the template name")
strModule = InputBox("Enter the module name")
strMacro = InputBox("Enter the macro name")
strParameter = InputBox("Enter a parameter value")
Application.Run MacroName:=strTemplate & "." _
& strModule & "." & strMacro, _
varg1:=strParameter