Permanently Save Variables with VBA? - vba

One of my many Userforms in Excel uses file paths to locate files to copy,move,delete depending on the situation. The majority of these file locations are always in the same directory and i am looking for a permanent way to store the file paths like a configuration file or settings files so VBA will allows look in the same place.
I was thinking about adding the String paths to the hidden personal workbook and reference each cell when assigning the variable but i develop on my machine and then rollout to other PC and i won't to avoid overwriting them.
I've heard text files can be used or SaveSettings() method which i've used before.
What would be the best way to accomplish this task and is it worth doing?

If it is for all users/different pcs then I can think of two ways.
Way 1
Store the values in Excel Settings.
Use the Application.DefaultFilePath to store the path and then read from it later. For example
Sub StorePath()
Application.DefaultFilePath = "C:\Temp"
End Sub
Sub GetPath()
MsgBox Application.DefaultFilePath
End Sub
Way 2
Store the values in the registry. See this small TUTORIAL I wrote couple of years ago.

Related

Excel: Is that possible to erase names from other files using vba macro?

Note : I am a total newbie in VBA and Excel, but I know my stuff in programming. This is why I am posting this for a friend of mine.
He tried to remove all names he had in his workbook (1 workbook = 1 file, right ?), so he applied this macro he found on the web, without exactly knowing what it does :
Sub Del_Name()
Dim Loop As Integer
For Loop = ActiveWorkbook.Names.Count To 1 Step -1
If MsgBox("Erase: " & ActiveWorkbook.Names(Loop).Name & " - " & ActiveWorkbook.Names(Loop).Value & "?", vbQuestion + vbYesNo, "Confirm...") = vbYes Then
ActiveWorkbook.Names(Loop).Delete
End If
Next
End Sub
Then, in his file's name manager there are names referencing to some other files, such as :
http://randomServer:port/user/randomFolder/[file.xls]randomSheet'!$AD$6:$AF$6
\\random\folder[anotherFile.xls]anotherSheet'!#REF!
He doesn't know where this names come from.
So, his concern, and my question here : is that possible that the vba macro erased names within distant files ? Is that even possible ?
I have looked hours for information about that, some posts I have read suggest this could be possible, but I am still quite confused, any help would be much appreciated.
Thanks in advance
no. it is not possible that the vba macro erased names within remote files.
all it did was to delete a list of links that were stored in the excel file.
same as if you delete a favourite link in your web browser, you are not actually changing anything on the website that link pointed to.
it is possible to use a macro to modify remote files. you must have access to the file system that contains the file and you must have "write" permission to that file. then you could open the file and update it. or run an update SQL query. plus some other ways that i cannot think of right now.

VBA Dynamic Save As, Microsoft Project to Excel

I am trying to create a macro that will export a Microsoft Project file into an excel file. Through the use of macro recording I have got a line of code that accomplishes this using the export wizard, but I want the file path and file name to be dynamic so I can use this macro on different projects. I have been searching many other threads and the Microsoft website with no luck. Is this possible?
Here is what I have:
sub formatAndSave ()
FileSaveAs Name:="C:\Users\XXXXXX\SharePoint\Projects\ProjectType\HxH\myProject.xlsx",_
FormatID:="MSProject.ACE", map:="myMap"
end sub
One idea I tried was:
Active.Workbook.SaveAs FileName:=Title
Any help would be very much appreciated!
For the sake of simplicity, let's assume for all answers below your project is located at c:\projects\myProj.mpp
I think you're after the string replace function. Something like:
Dim excelFilePath As String
excelFilePath = Replace(ActiveProject.FullName, ".mpp", ".xlsx")
Debug.Print excelFilePath
'the output would be c:\projects\myProj.xlsx
If you're unfamiliar with string manipulation in VB/VBA, just search the web for "VBA string manipulation". Microsoft has a decent article here: https://msdn.microsoft.com/en-us/library/aa903372(v=vs.71).aspx
A few other things that may be handy for you are these variables:
ActiveProject.FullName 'shows full path & name, so you'd get "c:\projects\myProj.mpp"
ActiveProject.Path 'shows just the path, so you'd get "c:\projects\"
ActiveProject.Name 'shows just the file name, so you'd get "myProj.mpp"
Finally, one caveat I've seen is that the ActiveProject.FullName and ActiveProject.Name variables may or may not provide the file extension depending on your local windows environment settings. I've observed that if Windows Explorer is configured to hide file extensions, then these variables also withhold the extension; if Explorer is configured to show them, then they are provided in the variables. Make sure your code is robust to both cases, or make sure you have control over the environment where you code will run.

Excel 2007 VBA use string variable value in object variable

Good afternoon guys!
I looked around, but I'm not finding anything that addresses my particular issue, so I'll do my best to explain.
Specs:
Excel 2007, VBA, Outlook 2007
Okay, so I've been reworking some scripts that I created to automate our reports in Excel / Avaya CMS. For the past few years I've been the sole person doing our reports, so it wasn't ever necessary to set things up on anyone else's computers. However, things are changing and I'm in the process of updating the scripts / training others to use them. At the moment, when I put my scripts on their computer, I have to go into the VBA code and manually set every reference to their own relative folder paths / outlook folder paths. Painless enough, except when I do any type of changes to the scripts and have to go through the whole process again on each computer.
So this was my solution: Create a config worksheet on the automated reporting workbook, on that config worksheet store the file paths, and in the code simply use variables to reference the config worksheet. This should make it as easy as setting the variables once from the config on a new computer without having to touch any of the lines of code.
Problem: At midnight there is data that is emailed to us from another office. We use Outlook at this office, so I've simply been having it go to the folder specified in the scripts, download the attachments, and then use the downloaded data for the reports. Since everyone sets up their own outlook folders, the paths inside of outlook are different for each user. Since VBA is accessing a worksheet to grab the config information from a cell, it's returning the path for Outlook folders as a string value. However, the outlook folder variable is of Object type, and so it doesn't allow me to use the string variable as it's value, even though the string itself is the actual value the object needs (just not as a string). So is it possible to convert the string value to a value that can be used in the Object variable?
Worksheet Config Cell Value (B5)- The String Value
outNamespace.Folders("Mailbox - Some Guy").Folders("Reports").Folders("ImportantData")
Code:
'Config tab
Dim serverConfig As Worksheet
Set serverConfig = Sheets("CONFIG")
Dim dirOutlookData As String
dirOutlookData = serverConfig.Range("B5").Value
Dim outFolder As Object
Set outFolder = dirOutlookData
Any ideas? Since the string that's returning for dirOutlookData is the value needed for the object variable value, how can I convert the value from the string variable so it can be used in such a way?
Thanks in advance.
Seems too convoluted a solution. Nobody could share their VBA.
In the example provided
outNamespace.Folders("Mailbox - Some Guy").Folders("Reports").Folders("ImportantData"
you could instead use this directly in the VBA
Set mailboxFolder = outNamespace.GetDefaultFolder(olFolderInbox).Parent
You now have the "Mailbox - Some Guy" folder in a generic way not needing to specify "Some Guy".
Set myFolder = mailboxFolder.Folders("Reports").Folders("ImportantData")

Batch add a macro to word documents?

I have several hundred .doc word documents to which I need to add a macro which runs when the .doc file is opened and creates a header for said document based on the file name. Is there a way to do this as a batch? I have been individually opening each document and going into visual basic --> Project --> This Document then inserting a .txt file which contains the code. Is there a fast way to do this for multiple documents?
As a learning exercise, put this into the "ThisDocument" part of Normal (the Normal.dot template) in the VBE
Open a word document and watch what happens.
I don't think you need to put your code in every single file, I think you should be OK with using the Document_Open event in Normal.dot.
Just make sure it shows up as a reference in your word documents that you open but I don't see why it wouldn't
If you absolutely need it in every file then it can be done but the problem is if you make one small change to the code, you have to go through all this again. The idea with code is to write it once, use it many times.
You can write VBA code that alters the VBA code in other documents, but you need to "Trust access to the VBA project object model" in the Trust Centre options. This could open you up to viral code if you download Word documents with malicious VBA code in them. What you want to do, essentially, is write a VBA virus. There are legitimate reasons for doing this, and also malicious ones, I leave the ethics of the uses of these techniques up to the user. Knowledge itself is not malicious.
Here's the meat, you will need to write your own code to loop through the documents and possibly save them as .docm files.
Sub ReplaceCode()
Set oDoc = ActiveDocument
Set oComponents = oDoc.VBProject.VBComponents
For i = oComponents.Count To 1 Step -1
If oComponents(i).Type = 100 And oComponents(i).Name = "ThisDocument" Then
With oComponents(i).CodeModule
.DeleteLines 1, .CountOfLines
.AddFromFile "C:\ThisDocument.cls"
End With
End If
Next i
End Sub
Also, if you create your code file by exporting from VBA, you will need to remove this from the top of the .cls file:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Personally, I would drive this from Excel, maybe using a worksheet to hold a list of the files or locations to update, and another sheet for the code to populate with a list of files updated.

VBA fails to find a file

I have a VBA script used to process Word documents. The first thing the program does is to create an index of the documents in a defined set of folders. It then goes through the list processing each of the indexed documents.
The problem I am having is that it will sometimes decide that a particular document cannot be found, even though it previously indexed the document and a quick spot check shows the document to be in the correct place.
Can anyone shed some light on why VBA should display this behaviour?
The script is using the Dir$ function to index the files, and the Documents.Open function to open each word document for processing.
Sample code:
ChangeFileOpenDirectory (folderName)
inputFileName = Dir$(folderName & "*.doc")
Do While inputFileName <> ""
... call various functions here ...
inputFileName = Dir$
Loop
One of the functions called in the block has the following line:
Set currentDoc = Documents.Open(fileName:=docFileName, AddToRecentFiles:=False, Visible:=False)
This is the point at which the code is failing.
One of the most annoying things I have found is that recent files links are returned as the files themselves with Dir. You can use the FileSystemObject to check the file type.
I copy/paste your code and it works correctly.
However, it leaves all the files open (and hidden), and when you run it in another directory, additional files are opened and added to the open projects (take a look in the VBA editor).
My only guess is that after a while you're hitting the maximum allowable number of open files.
Try adding
currentdoc.Close
just before
inputFileName = Dir$
A few reasons, some duplicated from other answers:
If the path+ filename is long enough ... (you already answered in a comment)
If you are writing new files to same directory, Dir$ may get corrupted (happened to me)
If you have filenames with non-std chars (ex. "#")
Files locked by other processes
Files deleted while the macro is running
You may also try this code ...
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(file) Then ....
First enable the Microsoft Scripting reference in the VBE