I'm new to VBA, so I'm struggling with this for a couple of days now.
I have a combobox in Word with contacts, I also have an excel file(contacts.xls) with one column (names of the all the contacts). When I open the Word-document the Macro has to fill in the combobox with all the names from the excel file.
Is it possible to send me a working example of this for word 2007? Seems quite simple, but just can't get this to work...
Thanks in advance!
If you intend on reading from an Excel file in Word you are going to have to open it. It will use code like this:
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
'Start a new workbook in Excel
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Open("FileName.xlsx")
You will also probably want to go to Tools->References in the VB project and find whatever Excel library is on your machine (and check it of course). There are ways around this if needed, but it is easier.
You then can read the values from the workbook:
oBook.Worksheets(1).cells(1,1)
I'm not totally sure what the syntax to get it into the combo box is. Look up "combobox object members" in the vbe in word. There will be a list property, or something like that.
Sorry, I'm on a linux machine right now, so I can't debug exact code for you.
I have more full code for you now:
Option Explicit
Sub TestDropDownFromExcel()
Dim counter As Long
Dim xlApp As Excel.Application
Dim xlBook As Workbook
Dim oCC As ContentControl
Set oCC = ActiveDocument.ContentControls(1)
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\Path\To\MyFile.xlsx")
If xlBook Is Nothing Then
Exit Sub
End If
oCC.DropdownListEntries.Clear
For counter = 1 To 10
oCC.DropdownListEntries.Add Text:=xlBook.Worksheets(1).Cells(counter, 1), Value:=CStr(counter)
Next counter
xlApp.Visible = True
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Be aware that there is very little error checking going on here. Also, rather than the call to .Visible at the end, you can simply call .Close if you do not want the user to see it (for the final project, this is probably preferable. The deferencing (= Nothing) is good practice to have, but VBA cleans up automatically at the end of execution. Obviously I am assuming tyou want the first dropdown (ContentCOntrols(1)) but this may not be true.
Related
I'm after some advice, and certainly open to other suggestions on how to achieve what I'm trying to do here, so feel free to suggest alternatives.
I'm trying to build a quote document where we can automatically populate some fields (they will be product specifications) based on selecting an option in a list box. So far I've created my Drop Down List and populated with 2 options. I've then created 4 'specifications' I want to fill out and created a Content Control for each one.
What I'm trying to do at the moment is populate these content controls from an Excel sheet, where the different List Box items are titles of Sheets, and the specifications are in a column of each sheet.
Sub chillerdatafromexcel()
Dim xlApp As Object
Dim xlbook As Object
Set xlApp = CreateObject("Excel.Application")
Set xlbook = xlApp.Workbooks.Open("C:\Users\chris.garratt\Documents\Chiller Options.xlsx")
'Set xlbook.Sheets = ThisDocument.SelectContentControlsByTitle("Chiller Supplier")
ActiveDocument.SelectContentControlsByTitle("MaxCoolingPwr").Item(1).PlaceholderText = xlbook.Sheets(ActiveDocument.SelectContentControlsByTitle("Chiller Supplier").Item(1).Range).Cells(2, 2)
End Sub
Word example
Excel sheet
Any ideas welcome. I haven't done any text based coding / scripting for a long time, so feel free to dumb it down.
Thanks in advance.
Chris
See:
http://www.msofficeforums.com/word-vba/16330-how-import-list-excel-into-drop-down.html#post46287
Others you might find useful include:
Dependent Dropdown Content Controls
http://www.msofficeforums.com/word-vba/24661-help-cascading-dropdown-list.html#post77762
Hierarchical Dropdown Content Controls
http://www.msofficeforums.com/word-vba/29617-creating-reducing-drop-down-list.html#post94603
Dependent Text Content Controls
http://www.msofficeforums.com/word-vba/16498-multiple-entries-dropdown-lists.html#post46903
http://www.msofficeforums.com/word-vba/16498-multiple-entries-dropdown-lists-5.html#post120392
Content Control & Formfield Conditional Formatting
http://www.msofficeforums.com/word-vba/16505-change-color-according-dropdown-selection.html#post47254
Creating and Tallying Mutually-exclusive Checkbox Content Controls
http://www.msofficeforums.com/word-tables/12335-assigning-values-content-control-checkboxes-calculating-results.html#post33489
http://www.msofficeforums.com/word-tables/33248-content-control-checkbox-calculations.html#post107008
Adding a new row to a table in a document with Content Controls:
http://www.msofficeforums.com/word-vba/27809-code-add-new-row-table.html#post87989
http://www.msofficeforums.com/word-vba/13955-macro-add-row-table-word-form.html#post38461
https://www.msofficeforums.com/word-vba/43603-multiple-dependent-dropdown-lists-table-add-new.html#post145675
Thank you all for your input. macropod, I'm sure those links will come in very helpful as I continue with this project.
I spent some time working on this yesterday before the replies came in, and I did manage to crack it (It's amazing what walking away and coming back with a fresh pair of eyes will do).
In the end, I settled on this:
Sub chillerdatafromexcel()
Dim xlApp As Excel.Application
Dim xlbook As Excel.Workbook
Dim xlsheet As Excel.Sheets
Dim X As Integer
Dim ChillerOpt As String
Dim Offset As Integer
Set xlApp = CreateObject("Excel.Application")
Set xlbook = xlApp.Workbooks.Open(ActiveDocument.Path & "\Chiller Options.xlsx")
Offset = ThisDocument.SelectContentControlsByTitle("Chiller Supplier").Count
ChillerOpt = ThisDocument.SelectContentControlsByTitle("Chiller Supplier").Item(1).Range
For X = (Offset + 1) To (Offset + 4)
ThisDocument.ContentControls(X).Range = xlbook.Sheets(ChillerOpt).Cells(X, 2)
Next X
xlbook.Close
xlApp.Quit
End Sub
I have a few extra variables in there which will be relevant when I use this function in the context of a larger document. I was going for keeping it as flexible as possible. Avoiding hard coding. I have 4 cells in the spreadsheet I want to pull in, hence the X range.
Thanks for your help.
Chris
I use two screen monitors. The left monitor has an Excel Workbook opened. The right monitor has a Microsoft Word document opened. I use a Word Userform to bring data from the opened workbook to the opened Word document.
But sometimes I need to change the activated/selected worksheet (I mean, the one that is in front of the others; th3e one I can see), and I would like to do so from a button in my Microsoft Word userform.
The code below does not work, and I have no idea how to achieve that goal.
Please, would someone have an idea how to achieve that?
Sub ACTIVATE_WORKSHEET_ASDF()
Dim MyExcel As Excel.Application
Dim MyWB As Excel.Workbook
Set MyExcel = New Excel.Application
Set MyWB = MyExcel.Workbooks.Open("MY EXCEL WORKBOOK FULL PATH")
Dim ASDF As Worksheet
Set ASDF = MyWB.Sheets("ASDF")
ASDF.Select 'DO NOT WORK
ASDF.Activate 'DO NOT WORK
Debug.Print ASDF.Cells(1,1) 'DOES WORK!
MyWB.Close False
Set MyExcel = Nothing
Set MyWB = Nothing
End Sub
I have an SSIS package that creates and populates an excel sheet, it creates the sheet from a template file.
One of the issue's I had was that excel would change the format of the rows. I did a work around of inserting a header row and hiding it.
However I now need to script a VB task in SSIS that opens the excel sheet and deletes that specific row.
I've seen some articles online however have not been able to find any code I can try and replicate and my VB knowledge is very limited and I am really struggling.
SO far i've figured out how to delete the row.
Sub DeleteRow1()
Rows(4).Delete
End Sub
However i need to assign file strings and get the file to open and close as well...
after some discussions with a programmer here i managed to get some script to do exactly what I needed. Posting as an answer for anyone else out there who ever needs to do this in SSIS.
Dim xlApp As Excel.Application
Dim xlSheet As Excel.Worksheet
xlApp = New Excel.Application
xlApp.Workbooks.Open(Dts.Variables("NewFileName").Value.ToString)
xlSheet = xlApp.Workbooks(1).ActiveSheet
xlSheet.Rows(4).Delete()
xlApp.Workbooks(1).Save()
xlApp.Workbooks(1).Close()
xlSheet = Nothing
'
Dts.TaskResult = ScriptResults.Success
Uses a variable in SSIS to get the file name. This works perfectly although you do need to add Microsoft.Office.Interop.Excel Reference.
Sub deleteRow1()
Dim wkbk As Workbook
'You can also use an input box like this
' Dim wkbkname As Variant
' wkbkname = InputBox("Enter Workbook Name here.")
' Use wkbkname instead of wkbk then
Set wkbk = "Filename"
wkbk.Sheets(1).Rows(4).delete
End Sub
I hope that's what you were looking for.
I have some VBA code that copies stuff from Excel and pastes it into Word. The problem I'm having is how to open the spreadsheet. I can open it using an absolute path reference by
Workbooks.Open "C:\path\filename.xls"
I would prefer to reference the spreadsheet using a relative path reference. I was able to find code for relative path references from an Excel workbook to another one but it doesn't seem to work if you're doing it from Word.
Add a reference to Excel object library, then create an object in code and use that object to control an instance of Excel. Just make sure to avoid things like ActiveWorkbook, just in case.
After adding the reference:
Sub DoStuffWithExcelInWord()
Dim xl As Excel.Application
Dim wkbk As Excel.Workbook
Dim wk As Excel.Worksheet
Set xl = CreateObject("Excel.Application")
Set wkbk = xl.Workbooks.Open("C:\test.csv")
Set wk = wkbk.Sheets(1)
Debug.Print wk.Cells(1, 1).Value
xl.Quit
Set wk = Nothing
Set wkbk = Nothing
Set xl = Nothing
End Sub
You can create something very similar using Excel to automate Word too, if that's more of what you're looking for.
I have a Word document with two embedded Excel files (added using Insert -> Object -> Create From File) which I wish to modify using Word VBA. I have got to the point where I am able to open the embedded files for editing (see code below), but am unable to get a handle on the Excel workbook using which I can make the modifications and save the embedded file. Does anyone have a solution for this? Thanks in advance.
Sub TestMacro()
Dim lNumShapes As Long
Dim lShapeCnt As Long
Dim xlApp As Object
Dim wrdActDoc As Document
Set wrdActDoc = ActiveDocument
For lShapeCnt = 1 To 1 'wrdActDoc.InlineShapes.Count
If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
'This opens the embedded Excel workbook using Excel
wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
End If
End If
Next lShapeCnt
End Sub
Yikes, don't do what you're suggesting in your comment. You'll probably end up with multiple instances of Excel (check Task Manager and see how many there are after executing your code).
Firstly, add a reference to the Excel object library (Project->References & choose Microsoft Excel Object Library). Now you can declare your objects as bona-fide Excel types and use early binding rather than declaring them as "Object" and using late binding. This isn't strictly necessary, but apart from anything else it means you get Intellisense when editing your code.
You're doing the right thing right up until you do .OleFormat.Edit. (I would personally use .OleFormat.Activate but since I've never tried using .Edit I couldn't say that it makes a difference).
Having done .Activate (or, presumably, .Edit), you can then access the OleFormat.Object member. Since the embedded Object is an Excel chart, the "Object" will be the Excel Workbook, so you can do this:
Dim oOleFormat as OleFormat
Set oOleFormat = ...
oOleFormat.Activate
Dim oWorkbook As Excel.Workbook
Set oWorkbook = oOleFormat.Object
' Do stuff with the workbook
oWorkbook.Charts(1).ChartArea.Font.Bold = True
Note that you do NOT need to close Excel, and indeed you cannot - Word "owns" the instance used for an edit-in-place, and will decide when to close it. This is actually something of a problem, since there's no obvious way to force the embedded object to be de-activated, so the chart would stay open after you execute the code above.
There is a hack-y way to get the chart to close, though. If you add tell Word to activate it as something else, it'll de-activate it first. So, if you tell it to activate it as something non-sensical, you'll achieve the right result because it'll de-activate it and then fail to re-activate it. So, add the following line:
oOleFormat.ActivateAs "This.Class.Does.Not.Exist"
Note that this will raise an error, so you'll need to temporarily disable error handling using On Error Resume Next. For that reason, I normally create a Deactivate method, to avoid disrupting the error handling in my main method. As in:
Private Sub DeactivateOleObject(ByRef oOleFormat as OleFormat)
On Error Resume Next
oOleFormat.ActivateAs "This.Class.Does.Not.Exist"
End Sub
Hope this helps.
Gary
I have a solution to my own problem. Any further comments will be appreciated -
Sub TestMacro()
Dim lNumShapes As Long
Dim lShapeCnt As Long
Dim xlApp As Object
Dim wrdActDoc As Document
Set wrdActDoc = ActiveDocument
For lShapeCnt = 1 To 1 'wrdActDoc.InlineShapes.Count
If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
Set xlApp = GetObject(, "Excel.Application")
xlApp.Workbooks(1).Worksheets(1).Range("A1") = "This is A modified"
xlApp.Workbooks(1).Save
xlApp.Workbooks(1).Close
xlApp.Quit
End If
End If
Next lShapeCnt
End Sub
Have another hackey way to get the chart to close: Simply use the find function to find something in the document that is not there.
EG
With Selection.Find
.ClearFormatting
.Text = "wiffleball"
.Execute Forward:=True
End With
This will take you out of the embedded file, close the instance and back to the main document, you can just code from there.
Hope this helps, this problem was driving me crazy.
When you grad the xlApp, you don't grab a specific workbook. So if you refer to a number, you may not be on the embeded file. Better use Activeworkbook.
For me workbook(1) turns out to be my personnal hidden xl file containing my personnal macros.
I don't do the tests as I only have one shape in my .docx but I think the number "Excel.Sheet.8" is rather .12 for me.
Sub TestMacro()
Dim lNumShapes As Long
Dim lShapeCnt As Long
Dim xlApp As Object
Dim wrdActDoc As Document
Set wrdActDoc = ActiveDocument
For lShapeCnt = 1 To 1 'wrdActDoc.InlineShapes.Count
If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
Set xlApp = GetObject(, "Excel.Application")
xlApp.ActiveWorkbook.Worksheets(1).Range("A1") = "This is A modified"
'xlApp.ActiveWorkbook.Save
'xlApp.ActiveWorkbook.Close
xlApp.Quit
End If
End If
Next lShapeCnt
End Sub
When I quit xlApp, the focus gets out of the embeded xl. No problem with that.