I want to create a marco which enables me to add something in an excel sheet while working in Word. I managed to get something working which opens an excel file from word:
Dim excelApp As Excel.Application
Dim openExcel As Workbook
Dim var1 As Integer
Set excelApp = New Excel.Application
Set openExcel = excelApp.Workbooks.Open("C:\Documents and Settings\aa471714\Desktop\Book1.xls")
excelApp.Visible = True
But now I want to add the code which should happen in excel right after. But when I add the relevant code:
Sheets("Sheet2").Select
Range("A4").Select
This does not seem to work. Am I overlooking something?
Dear regards,
Marc
Keep in mind that in macro created in Word default application is Word Application all the time. Therefore each time you want to make any operation in Excel you need to state it by adding full references to Excel Application (or other Excel object as presented below).
Keep also in mind that you will need to add extended object hierarchy in such situation.
Back to your code- adding this kind of object references should solve the problem:
(incl. some additional re-editions)
'comments referring to Object hierarchy
openExcel.Sheets("Sheet2").Select 'OK because sheet is an object below Workbook
excelApp.Range("A4").Select 'NEW, Range is object below Application or...
openExcel.Sheets("Sheet2").Range("A4").Select 'IMPROVED, Range is object below sheet
'general- Range.Select works only for activesheet!!
Object openExcel keeps reference to Excel application which is represented by excelApp.
Related
The code is:
Sub Copy_Filtered_Table()
Dim aSheet As Worksheet
Dim i As Long
i = ActiveSheet.Index
ActiveSheet.AutoFilter.Range.Copy
-> Set aSheet = ActiveWorkbook.Worksheets.Add(After:=i)
aSheet.Range("A1").PasteSpecial
End Sub
The workbook format is .xlsm Excel 2016
it has sheets after and before the active sheet
Also I Have tried doing it with out the aSheet variable like this
ActiveWorkbook.Worksheets.Add After:=i
It did not work too. both cases gives error 1004 Method 'Add' of object 'Sheet' faild.
If I ommited the After parameter it works but putting the result new sheet before the active sheet which exactly I am avoiding.
In order to insert relative to an existing sheet, you need to provide the actual sheet rather than its index, using one of:
Set aSheet = ActiveWorkbook.Sheets.Add(After:=ActiveWorkbook.Worksheets(i))
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Worksheets(i)
Which one you choose depends on whether you immediately want to do something with the sheet without searching for it again but I suspect you already know that, given your question.
As an aside (though I haven't tried), I suspect getting the index of the current sheets then turning that back into the current sheet object is a bit unnecessary. You may want to just try:
Set aSheet = ActiveWorkbook.Sheets.Add(After:=ActiveWorkbook.ActiveSheet)
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
In MS Access, I am writing a small piece of code to insert a row into a .xlsx file. Both files are local. The code runs with no errors, but, each time it runs, it renders the .xlsx file unreadable. Here's a step-through:
(1) I have the simple .xlsx file (a few hundred rows, a dozen columns, a bit of formatting, no special features or embedded VBA).
(2) I can open and view the file in Excel - but I make sure I close it before running the code.
(3) Run the code below, in MS Access.
(4) The code executes with no errors. The debug.print performs as expected and prints out the contents of cell(1,1).
(5) I re-open the .xlsx file in MS Excel, but Excel now can't open it. Excel itself opens, but, remains completely blank with no open file. No errors.
(6) If I use Office365 to open the file (via web front end), then, it says the following error:
"We can't open this workbook. It's set to show only certain named items, but they aren't in the workbook."
I can restore the file easily enough, but the same behaviour occurs each time (5 times, I've tested - each with slightly different .insert methods). Is there something in my code which is causing this?
Public Function WriteHistoryToExcelFile()
Dim lExcelObj As Excel.Application
Dim lExcelWB As Excel.Workbook, lSheet As Excel.Worksheet
Set lExcelObj = CreateObject("Excel.Application")
Set lExcelWB = GetObject("C:\Users\XXX\OneDrive\AA-Store\Ziggy\Meta History.xlsx")
Set lSheet = lExcelWB.Sheets(1)
Debug.Print lSheet.Cells(1, 1) 'This works correctly
lSheet.Rows(1).Insert
lExcelWB.Save
lExcelWB.Close
Set lExcelWB = Nothing
Set lExcelObj = Nothing
End Function
Can someone reproduce this awkward behaviour?
Instead of using GetObject to open the workbook, try using the Application.Workbooks.Open method. And explicitly Quit Excel too:
Public Function WriteHistoryToExcelFile()
Dim lExcelObj As Excel.Application
Dim lExcelWB As Excel.Workbook, lSheet As Excel.Worksheet
Set lExcelObj = CreateObject("Excel.Application")
Set lExcelWB = lExcelObj.Workbooks.Open("C:\Users\XXX\OneDrive\AA-Store\Ziggy\Meta History.xlsx")
Set lSheet = lExcelWB.Sheets(1)
Debug.Print lSheet.Cells(1, 1) 'This works correctly
lSheet.Rows(1).Insert
lExcelWB.Save
lExcelWB.Close
lExcelObj.Quit
Set lExcelWB = Nothing
Set lExcelObj = Nothing
End Function
You might also want to make sure you don't have any lingering, hidden copies of Excel running, in Task Manager.
I'm reading data from an excel spreadsheet in a word macro so I can use the spreadsheet to instantiate a document from a template and set properties in the instantiated document from the excel table. I'm trying to be as explicit with types as I can, but it turns out that the object that comes back from an excel selection has rows typed differently than a row in a word document. Not actually that surprising now that I think about it. Is there a common base class more specific than Object between an excel spreadsheet row type and a word table row type? Maybe a way to specify that excel row type? Or is my best bet to use the Object type and not worry about the details. Dynamic typing is amazing here, most of the class methods are the same.
I am also interested in running word based VBA subroutines (located in normal) from excel VBA. I tried to look it up via Google but did not have any luck.
The guts are here:
Set testList = LoadExcel(strFile)
testList.Activate
Dim allSuites As Object
' LoadExcel also selects the rows that contains the data we want in excel
Set allSuites = testList.sheets("FullSuiteList").Application.Selection
Dim myRow As row
Dim Columns() As String
Dim i As Integer
' Previously I used a table in word, but there are too many columns
' to be manageable
' LoadPropertyNames testList.Tables(1).Rows(1), Columns
' For i = 2 To testList.Tables(1).Rows.Count
' Now we get data directly from our Excel sheet
LoadPropertyNames allSuites.Rows(1), Columns
For i = 2 To allSuites.Rows.Count
CreateOne allSuites.Rows(i), Columns
Next I
' row type yields type mismatch at runtime. myrow as Object works though.
Function LoadPropertyNames(myRow As row, Columns() As String)
...
End Function
' row type yields type mismatch at runtime. myrow as Object works though.
Function CreateOne(myRow As row, Columns() As String)
...
End Function
In the VBA editor, in the Tools menu choose References then add "Microsoft Excel ##.# Object Library" to your Word VBA project. This will give you access to all of Excel's objects. Note that some object names, e.g. "Range" represent different objects in Word vs Excel, so declare variables as Word.Range or Excel.Range as appropriate.
To answer your question in the comment about running one of the Normal template's subroutines. First in Excel add a reference to the the Word object model --- in the Tools menu choose References then add "Microsoft Word ##.# Object Library" to your Excel project. Then here's an example of how to call a Normal template sub:
Sub RunNormalTemplateSub()
Dim wdapp As Word.Application
Dim wddoc As Word.Document
Set wdapp = New Word.Application
wdapp.Visible = True
' This is the line that runs the sub
' This runs a sub named "ThisIsATest"
' in the module "Sandbox"
' in the Project/Template "Normal"
wdapp.Run "Normal.Sandbox.ThisIsATest"
' If the sub takes arguments then you would call
' wdapp.Run "Normal.Sandbox.ThisIsATest", Arg1, Arg2
Set wdapp = Nothing
End Sub
Note that Word is running the subroutine. I don't know of a way to have Excel run the Word subroutine (maybe it can be done, but I don't know how).
Hope that helps
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.