Store file inside VBA Project and open it - vba

I have created a VBA Application in MS Excel 2010. It has one user form. There I'd like to add a feature to open a (MS Word) file for support and FAQ purposes. I do not want to save the file at a central location and open the file then via VBA. Is there a possibility to store the file maybe inside the vba project?

You can embed an object in an Excel Worskeet (Insert -> Object). If you click on the embedded object, in the upper left corner you will see the name of the object (e.g. "Object 7"). With that you can open it in vba via
Sub openEmbed()
Dim ole As OLEObject, wdoc As Word.Document
Set ole = Worksheets("Sheet1").OLEObjects("Object 7")
ole.Activate
Set wdoc = ole.Object
End Sub

You could store the content as XML in the VBA and then insert it with InsertXML in a new document:
Dim app As Object
Set app = CreateObject("Word.Application")
app.Visible = True
app.Documents.Add.Content.InsertXML "<?xml version=""1.0""?><abc:books xmlns:abc=""urn:books"" " & _
"xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" " & _
"xsi:schemaLocation=""urn:books books.xsd""><book>" & _
"<author>Matt Hink</author><title>Migration Paths of the Red " & _
"Breasted Robin</title><genre>non-fiction</genre>" & _
"<price>29.95</price><pub_date>2006-05-01</pub_date>" & _
"<abstract>You see them in the spring outside your windows. " & _
"You hear their lovely songs wafting in the warm spring air. " & _
"Now follow their path as they migrate to warmer climes in the fall, " & _
"and then back to your back yard in the spring.</abstract></book></abc:books>"

Related

Access Code partially stopped working (not populating data to word document)

I have an Access database with linked tables. I have created a code to do the following:
1- Create a folder in a specific location with a specific name (name populated from data in access).
2- Open a word document saved in a specific path
3- I then use formfields in the document to populate the word document with data from the table
4- Lastly, I save the word document to the previously created folder with a new name using data from the table
I have been using this code successfully for well over a year with no issues.
Suddenly, for no apparent reason and without any change to the code it stopped populating the word document with data. note, its still doing steps 1,2, & 4 but not step 3.
I cannot figure out what the issue is and any help would be much appreciated.
Below is a sample of the code used:
Sub Onboarding_Documents_Saudi_Click()
'STEP ONE: create the appropriate Folder
Dim fs, cf, strFolder
On Error Resume Next
strFolder = "C:\Users\1161\OneDrive - Anfas Medical Care\Master - Anfas Medical Care\New Employees\" & Me.Name_In_English & " " & Me.Emp_Id
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FolderExists(strFolder) = True Then
MsgBox "'" & strFolder & "' already exists!"
Else
Set cf = fs.CreateFolder(strFolder)
If fs.FolderExists(strFolder) = True Then
MsgBox "'" & strFolder & "' successfully created!"
Else
MsgBox "'" & strFolder & "' was not successfully created!"
End If
End If
'STEP TWO:Make Contract .
Dim appWord As Word.Application
Dim doc As Word.Document
Dim Base As String
Base = Format(Me.base_salary, "Standard")
Dim Housing As String
Housing = Format(Me.housing_allowence, "Standard")
Dim Trans As String
Trans = Format(Me.transportation_allowence, "Standard")
On Error Resume Next
Err.Clear
Set appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set appWord = New Word.Application
End If
Set doc = appWord.Documents.Open("C:\Users\1161\OneDrive - Anfas Medical Care\Master - Anfas Medical Care\Forms\Onboarding Documents\Access\Saudi\ContractSaudiAccess.docx", , True)
With doc
.FormFields("frnameinarabic").Result = Me.Name_In_Arabic
.FormFields("frnameinenglish").Result = Me.Name_In_English
.FormFields("frid").Result = Me.Document_ID_number
.FormFields("frmobile").Result = Me.mobile_number
.FormFields("frjtenglish").Result = Me.Job_title_English
.FormFields("frjtarabic").Result = Me.Job_Title_Arabic
.FormFields("frbasesalary").Result = Base
.FormFields("frhousing").Result = Housing
.FormFields("frtrans").Result = Trans
.FormFields("fremail").Result = Me.Personal_Email
.FormFields("empid").Result = Me.Emp_Id
.FormFields("joindate").Result = Me.Join_Date
.FormFields("joindatehijri").Result = Me.[Join Date Hijri]
.FormFields("contractperiod").Result = Me.[Contract Length]
.FormFields("contractperiodar").Result = Me.[Contract Length Ar]
.FormFields("frdepartment").Result = Me.Department
.FormFields("frdepartmentarabic").Result = Me.Department_Ar
.FormFields("joindate1").Result = Format(Me.Join_Date, "dddd dd/mmm/yyyy", vbUseSystemDayOfWeek)
.Activate
.Visible = True
.Activate
End With
doc.Fields.Update
doc.SaveAs2 "C:\Users\1161\OneDrive - Anfas Medical Care\Master - Anfas Medical Care\New Employees\" & Me.Name_In_English & " " & Me.Emp_Id & "\" & FileName & "Contract " & Me.Name_In_English & " " & Me.Emp_Id & ".docx"
Set doc = Nothing
Set appWord = Nothing```
Could this be a change due to Office Updates? I have something similar which works with Word v1910 (Build 12130.20272) but not in v2301 (Build 16026.20146). That may explain the second machine suddenly not working also?
It appears opening the "template" document which you are then adding information into opens read only as requested but now no longer allows changes to be made, which is where I think your code is skipping too? Our running code displays the Word document after filling in the form fields and there is no option to change the file mode to the top right of the screen to allow editing.
Screen shot of viewing / editing options from Word toolbar
I don't have an answer as to how to fix it as yet, I'm afraid, apart from making the template document open for write access and changing rights on the network to make the documents read only. We've not tested that as yet though. Hopefully it helps by giving you something else to check as the code has run successfully for a time and suddenly stopped.
I'm currently trying to find an option for opening a file as read only but allowing changes to the open document but am struggling to find anything like this in the Microsoft documentation. If I do find a solution I'll come back and post it.
It may work for you changing the following line from True to False at the end if the file is somewhere not shared.
Set doc = appWord.Documents.Open("C:\Users\1161\OneDrive - Anfas Medical Care\Master - Anfas Medical Care\Forms\Onboarding Documents\Access\Saudi\ContractSaudiAccess.docx", , True)

Charts template folder

I've developed a superuseful addon which recreates source data for charts "disconnected" from Excel. So I .SaveChartTemplate then ApplyChartTemplate to a new chart, and need to delete temp. template.
Don't know how to get chart template folder. I assume that it's Environ("AppData") & "\Microsoft\Шаблоны\Charts\" but it's obvious that it works only with russian locale.
After analyzing registry keys, i've come to realize that templates folder name can be found in HKCU\Software\Microsoft\Office\<OFFICE VERSION>\Common\General\Templates
Assuming the above a possible solution is
Function chartTemplatesFolder() As String
On Error GoTo er:
Dim templatesFolder As String
templatesFolder = CreateObject("WScript.Shell").RegRead( _
"HKCU\Software\Microsoft\Office\" & Application.Version & "\Common\General\Templates")
chartTemplatesFolder = Environ("AppData") & "\Microsoft\" & templatesFolder & "\Charts\"
Exit Function
er:
End Function

Is it possible to add an XML "log" using CustomXMLParts in Excel VBA?

I have project that require I maintain log of users (using Application.UserName) that perform a certain actions with a macro-enabled Excel spreadsheet. I've tried using the VB examples found at the links list below and modifying for VBA, but I'm running into error at last line of Sub. Can anyone point me towards a better VBA example or guide me in the right direction?
http://msdn.microsoft.com/en-us/library/bb608627.aspx
http://msdn.microsoft.com/en-us/library/bb608612.aspx
Here's the code I'm currently working with.
Private Sub AddCustomXmlPartToWorkbook(ByVal Workbook As Excel.Workbook)
Dim xmlString As String
xmlString = _
"<?xml version=""1.0"" encoding=""utf-8"" ?>" & _
"<employees xmlns=""http://schemas.microsoft.com/vsto/samples"">" & _
"<employee>" & _
"<name>Karina Leal</name>" & _
"<hireDate>1999-04-01</hireDate>" & _
"<title>Manager</title>" & _
"</employee>" & _
"</employees>"
Dim employeeXMLPart As Office.CustomXMLPart
employeeXMLPart = ActiveWorkbook.CustomXMLParts.Add(xmlString)
End Sub
You just run the statement that adds the CustomXMLPart:
Call ActiveWorkbook.CustomXMLParts.Add(xmlString)
It is added to the end of the collection, so you know it's position by doing ActiveWorkbook.CustomXMLParts.Count

How to list DataMacro objects in an Access database?

Is it possible to programmatically enumerate the Data Macros in an Access 2010+ database? If so, how?
Note: Data Macros are trigger-like procedures that are created in the context of the table designer UI. They were new in Acces 2010. They are NOT the same thing as normal macros, which are easy to enumerate.
They have their own new AcObjectType enumeration value : acTableDataMacro, but I can find no other aspect of the Access or DAO object model that refers to them. They do not even appear in the MSysObjects table.
This code will export DataMacro metadata to an XML Document (Source):
Sub DocumentDataMacros()
'loop through all tables with data macros
'write data macros to external files
'open folder with files when done
' click HERE
' press F5 to Run!
' Crystal
' April 2010
On Error GoTo Proc_Err
' declare variables
Dim db As DAO.Database _
, r As DAO.Recordset
Dim sPath As String _
, sPathFile As String _
, s As String
' assign variables
Set db = CurrentDb
sPath = CurrentProject.Path & "\"
s = "SELECT [Name] FROM MSysObjects WHERE Not IsNull(LvExtra) and Type =1"
Set r = db.OpenRecordset(s, dbOpenSnapshot)
' loop through all records until the end
Do While Not r.EOF
sPathFile = sPath & r!Name & "_DataMacros.xml"
'Big thanks to Wayne Phillips for figuring out how to do this!
SaveAsText acTableDataMacro, r!Name, sPathFile
'have not tested SaveAsAXL -- please share information if you do
r.MoveNext
Loop
' give user a message
MsgBox "Done documenting data macros for " & r.RecordCount & " tables ", , "Done"
Application.FollowHyperlink CurrentProject.Path
Proc_Exit:
' close and release object variables
If Not r Is Nothing Then
r.Close
Set r = Nothing
End If
Set db = Nothing
Exit Sub
Proc_Err:
MsgBox Err.Description, , _
"ERROR " & Err.Number _
& " DocumentDataMacros"
Resume Proc_Exit
Resume
End Sub
EDIT: Gord pointed out that you wanted the DataMacros opposed to standard macros. I found some code and tested it (it works) here
I tested the top function when you follow that link and it saves information regarding your table macros for each table in an XML document. It works nicely, props to whoever wrote it.

FileDialog in Word 2011 VBA

I'm hoping for a bit of a sanity check. I'm adapting a Word add-in (written in VBA for Word 2010) for Mac, specifically, at this point, Word 2011. I'm aware of many of the differences, but one that I haven't been able to find much documentation on is the apparent lack of FileDialog. The closest I've come to an answer is here: http://www.rondebruin.nl/mac.htm where the author uses Application.GetOpenFilename. That method doesn't seem to exist for Word, though (the focus of that site is Excel).
Does anyone know how to use the file and folder picker dialogs that FileDialog makes available? I'm not familiar with Applescript, really, but I've had to learn a little in order to get around Word 2011's funky file management issues (Dir, FileCopy, etc.). So, if that's the answer, any sense of what the code might look like in Applescript would be greatly appreciated. (I more or less know how to translate that into VBA).
I believe you have to use Apple Script in order to do this a bit better on the Mac. The following code allows the user to select text files which is returned as an array from the function. You would simply be able to modify the Apple Script to return other file types and select directories, I'll leave that to you.
The code that calls the function and displays a message box with all the files:
Sub GetTextFilesOnMac()
Dim vFileName As Variant
'Call the function to return the files
vFileName = Select_File_Or_Files_Mac
'If it's empty then the user cancelled
If IsEmpty(vFileName) Then Exit Sub
'Loop through all the files specified
For ii = LBound(vFileName) To UBound(vFileName)
MsgBox vFileName(ii)
Next ii
End Sub
And the function that does the Apple Script work:
Function Select_File_Or_Files_Mac() As Variant
'Uses AppleScript to select files on a Mac
Dim MyPath As String, MyScript As String, MyFiles As String, MySplit As Variant
'Get the documents folder as a default
On Error Resume Next
MyPath = MacScript("return (path to documents folder) as String")
'Set up the Apple Script to look for text files
MyScript = "set applescript's text item delimiters to "","" " & vbNewLine & _
"set theFiles to (choose file of type " & " {""public.TEXT""} " & _
"with prompt ""Please select a file or files"" default location alias """ & _
MyPath & """ multiple selections allowed true) as string" & vbNewLine & _
"set applescript's text item delimiters to """" " & vbNewLine & _
"return theFiles"
'Run the Apple Script
MyFiles = MacScript(MyScript)
On Error GoTo 0
'If there are multiple files, split it into an array and return the results
If MyFiles <> "" Then
MySplit = Split(MyFiles, ",")
Select_File_Or_Files_Mac = MySplit
End If
End Function
Finally, it can be a bit of a pain specifying different file types, if you want to specify only Word documents, then replace public.TEXT with com.microsoft.word.doc, however this won't allow .docx or .docm files. You need to use org.openxmlformats.wordprocessingml.document and org.openxmlformats.wordprocessingml.document.macroenabled respectively for these. For more info on these see: https://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html