Excel 2007 VBA use string variable value in object variable - vba

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")

Related

How to refer to a relative path in SolidWorks VBA

I am writing a macro in SolidWorks VBA that is supposed to open all the parts of an assembly and update their design tables. When the assembly and parts are copied to a new location, I want the macro to open the new (copied) parts in their new location. How do I refer to a relative path for the parts instead of an absolute path.
Or: How do I program VBA to change the file location of the parts to the current folder?
I've found some info on how this works in Excel VBA, yet I can't seem to translate this to SolidWorks VBA.
Dim folderpath As String
folderpath = Application.Activeworkbook.Path
I can't figure out with what I should replace "ActiveWorkbook" to get the location of the current assembly. Searching the object browser in SW VBA doesn't show anything usefull either.
You'll want to use swModel.GetPathName. Here's an example.

Can a Variable be stored in an Excel File that can not be accessed through Excel

I just discovered that in MS Word it is possible to store a Variable in a MS Word File that can not be accessed through the regular interface when running Microsoft Word.
Sub SetMyVariable()
Dim VARNAME As String
VARNAME = "HiddenVar"
ActiveDocument.Variables.Add VARNAME, "My special info"
End Sub
This gets saved in the XML Schema under word\settings.xml
I have tried using the ThisWorkbook Object in Excel, but it doesn't seem to have a Variable object that can be added like in word.
I want to know if there is something similar in Excel to store information/varialbes that get saved with the file.
PS: the closest thing I can think of (and use in codig) is a hidden named range.
You can try with the CustomXMLParts property of the Workbook which from the link seems a generic feature of Office products and available in Excel. Given you noted that a user would have to manually inspect the XML within the unzipped xlsx files then this seems to map to the Word Variables feature. The code sample just substitutes ThisWorkbook for ActiveDocument:
Option Explicit
Sub TextXMLPart()
Dim objXMLPart As CustomXMLPart
'add
Set objXMLPart = ThisWorkbook.CustomXMLParts.Add("<foo>bar</foo>")
'inspect
For Each objXMLPart In ThisWorkbook.CustomXMLParts
Debug.Print objXMLPart.XML
Next objXMLPart
End Sub
The accepted answer to this question (which focuses on Excel and vsto) states that:
Custom XML parts For an application-level add in, this is my preferred method of storing any application data that needs to be persisted in a saved xls file without ever being visible to the user.

How to access a Word public variable in Excel VBA

I'm trying to automate some report generation where Excel VBA is doing all the work. My employer has a standardized set of templates of which all documents are supposed to be generated from. I need to populate one of these templates from Excel VBA. The Word templates utilize VBA extensively.
This is (some of) my Excel VBA code:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
WordApp.Documents.Add Template:="Brev.dot"
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
' more code
End sub
In the Word VBA Autoexec module, a public variable named user is defined and declared. The Userinfo sub from the Utilities module populates user. Both these routines are run without any complaints from VBA. I would then like to be able to access the user variable in my Excel VBA, but I get the following error
Compile Error: Variable not yet created in this context.
How can I access the Word VBA variable in Excel VBA? I thought it more or less was the same?
EDIT: the user variable is a user defined Type with only String attributes. Copying the Word VBA functions that populate the user variable is absolutely doable, just more work than I though was necessary...
In a Word module:
Public Function GetUserVariable() As String '// or whatever data type
GetUserVariable = user
End Function
In an Excel module:
myUser = WordApp.Run("GetUserVariable")
Alternatively, you could be able to replicate the variables value - as it's called user I suspect it is returning some information about a user, or author, of a document. In which case one of the following might be what you're after:
'// Username assigned to the application
MsgBox WordApp.UserName
'// Username defined by the system
MsgBox Environ$("USERNAME")
'// Name of the author of the file specified
MsgBox CreateObject("Shell.Application").Namespace("C:\Users\Documents").GetDetailsOf("MyDocument.doc", 9)
Another option - if you could only add a line of code to the Utilities.UserInfo sub (after setting your public variable):
ActiveDocument.Variables("var_user") = user
Then you could access it easily afterwards in Excel:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
'I am assuming your WordApp object is public, as you don't declare it.
'Capture the new document object
Dim newdoc as Object
set newdoc = WordApp.Documents.Add(Template:="Brev.dot")
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
'Get and show the value of "user"
Dim user as String
user = newdoc.Variables("var_user")
msgbox, user
End Sub
This is assuming that useris a string.
EDIT: As it is a requirement to work only on the Excel VBA, I would definely try the approach suggested by Scott and MacroMan - replicating the same functionality of the Word macros in Excel - if possible.
I assume that you've already ruled out the possibility of using an edited copy of the original template, set in a public folder...
For the sake of completness, there is another possibility: actually it is possible to inject VBA code in a Word document without the VBProject Object Model, by "brute force". If you rename a Word document as a .zip file and open it, you will notice a \word\vbaProject.bin file in it. This file contains the VBA project for the document and, in principle, one could add or change VBA code by modifying or replacing it.
I did some tests transplanting code from one document to another by simply copying the vbaProject.bin file, and the concept works. If you are interested in learning more about this file, this topic could be of use.
Notice, however, that to do what you want with such a technique would be somewhat complex (it would involve, for starters, updating zip files from your Excel VBA), and would require a lot of experimentation to mitigate the risk of accidentally corrupting your files. Definetly not recommended if you are looking for an easy and simple solution - but it is possible.

Can't open xlsm file from SSIS package job

I have a number of SSIS jobs that open some Excel files and manipulate them. The task within the job that opens the Excel file is basically the same in each job, it just points to a different Excel file. Each of these jobs work fine except for one. But even this one works when ran manually from the package and not in the job.
The applicable code is:
Dim reportLocation As String
Dim oXL As Microsoft.Office.Interop.Excel.Application
Dim oWB As Microsoft.Office.Interop.Excel.Workbook
reportLocation = "\\testlocation\share\test.xlsm"
'Open Excel instance
oXL = New Microsoft.Office.Interop.Excel.Application
oXL.Visible = False
'Open the Excel file to edit
oWB = oXL.Workbooks.Open(reportLocation) 'Error here
The error received is as below:
Microsoft Excel cannot access the file '\\testlocation\share\test.xlsm'.
There are several possible
reasons:
• The file name or path does not exist. • The file is being used by
another program. • The workbook you are trying to save has the same
name as a currently open workbook. at
Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object
UpdateLinks, Object ReadOnly, Object Format, Object Password, Object
WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin,
Object Delimiter, Object Editable, Object Notify, Object Converter,
Object AddToMru, Object Local, Object CorruptLoad) at
ScriptTask_ffa2c543b1224c3987d5764694df1079.ScriptMain.Main()
This was the latest package to be created, and was a copy/paste job, just changing the locations it looks for the files. I have checked all permissions and there is no issue there. I've even given access to "Everyone" to see if that was an issue, but the same error occurred. The file definitely exists in the location and it is not open by anyone. What possible reason is there that this specific file can't be opened when run in a SQL job but can be opened when run manually in the package? I have also tried changing the job to run the package as a user with full admin access via a proxy. But still no joy.
This does not look like a valid path to me:
\\testlocation\test.xlsm
You at least need a share name after the host name:
\\testlocation\Share\test.xlsm
How do the paths look for your working files? I'm guessing they have a share.
Having revisited some answers on here for similar questions I was able to find the solution. This can be seen at Microsoft Office Excel cannot access the file 'c:\inetpub\wwwroot\Timesheet\App_Data\Template.xlsx'
I created the directory C:\Windows\SysWOW64\config\systemprofile\Desktop on the server and it miraculously now works. I had looked at this yesterday and thought the directory already existed so didn't implement this solution. But having a second look at it today shows the directory didn't exist and creating it fixed it.
Now the question is, why does this work?! But that is possibly another question.

Setting a constant from a variable value

I would like to set the path of my database as a constant.
The problem is that the path is stored in a INI file and the variable is set when Outlook is launched. VBA won't compile if the constant isn't hardcoded.
The reason why I want to use a constant is because, for some reasons, after a few hours/days with Outlook running, it sometimes seems to lose the value of its variables (never experienced this problem with a hardcoded constant). The path variable just get emptied, and then when VBA tries to reach the database, the user gets an error.
I can't hardcode the path just because some users don't use the same server UNC path. This path might change once a year or so, it's easier to just edit the INI file and restart Outlook than ask for a programmer to edit the right line in the code on each user's computer.
Any ideas?
You cannot change the value of a constant at run-time. Those values are set when the code is compiled (even if you don't explicitly compile VBA code it is still done Just-In Time (JIT) in the background).
If you don't want to be constantly running the lookup code (because it is inefficient, for example), than you can use a static variable within a function:
Function GetDbPath() As String
Static DbPath As String
If Len(DbPath) = 0 Then
DbPath = 'your code here'
End If
GetDbPath = DbPath
End Function