To end the instance created from VBA code in Task manager - excel

I have written a VBA(Access) code to export data from Access database to Excel Worksheet. At the end of the code I have closed all the objects, Recordsets, worksheets and respectively 'nothing' is set.After the first run, I check the task Manager, I see an instance of Excel still exist in it. After the export, If I close the Access Database the instance in the Task Manager is ended. Is this normal ? or Do I have to edit my code?
Disdavantage: I am not able to run the code for second time when the database is still open.
Below is my code
Public Sub Expdata()
Dim rst As DAO.Recordset
Dim xlWBk As Object, Apxl As Object
Dim wsMetaData As Worksheet
Dim wsPlanning As Worksheet
Dim PathEx As String
Dim i As Long
Dim Tempsheetname As String
Dim blnEXCEL As Boolean
blnEXCEL = False
On Error Resume Next
Set Apxl = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Set Apxl = CreateObject("Excel.Application")
blnEXCEL = True
End If
Err.Clear
On Error GoTo 0
PathEx = Forms("Export").Text14 'path comes from the directory given in form
'Set Apxl = CreateObject("Excel.Application")
Set xlWBk = Apxl.Workbooks.Open(PathEx)
Tempsheetname = "Metadatasheet"
Worksheets.Add.Name = Tempsheetname
Set wsMetaData = xlWBk.Worksheets("Metadatasheet")
Set wsPlanning = xlWBk.Worksheets("PlanningData")
Apxl.Visible = True 'uncomment for debug to see excel file
Set rst = CurrentDb.OpenRecordset("LatestSNR")
For i = 1 To rst.Fields.Count
wsMetaData.Cells(1, i).Value = rst.Fields(i - 1).Name
Next i
rst.MoveFirst
wsMetaData.Range("A2").CopyFromRecordset rst
'calls Exp_Refresh module
Call Exp_Refresh.RfData(xlWBk)
Set xlWBk = Apxl.Workbooks.Open(PathEx)
xlWBk.Sheets("Metadatasheet").Select
DoCmd.SetWarnings False
xlWBk.Application.DisplayAlerts = False
xlWBk.Sheets("Metadatasheet").Delete
DoCmd.SetWarnings True
xlWBk.Application.DisplayAlerts = True
'Close all the objects and recordsets
rst.Close
Set rst = Nothing
xlWBk.Close SaveChanges:=True
Set xlWBk = Nothing
Set wsMetaData = Nothing
Set wsPlanning = Nothing
If blnEXCEL = True Then Apxl.Quit
Set Apxl = Nothing
MsgBox "Export Successful !!!"
End Sub

It's Excel not closing? Then CreateObject on the workbook, not ExcelApp.
Also if excel is set to visible then the rules of COM says you do not close if the user can see it.

After a bit of research.. I found the error point
Tempsheetname = "Metadatasheet"
Worksheets.Add.Name = Tempsheetname
At this point it had lost its reference from the object. So if "Access app has ANY reference to an Excel resource, Excel won't close".
All I had to do was;
Tempsheetname = "Metadatasheet"
xlWBk.Worksheets.Add.Name = Tempsheetname

Related

Can't create Excel spreadsheet from Word

I'm trying to write a VBA macro from within Word to create an Excel spreadsheet and export data to it. I'm having trouble just creating the new spreadsheet. For the following macro, I get "Object doesn't support this property or method" on the line
Set myWb = myExcel.Workbooks.Add
in the code
Private Sub CreateExcel2()
Dim myExcel As Object
Dim myWb As Object
Set myExcel = CreateObject("Excel.Application")
Set myWb = myExcel.Workbooks.Add
Application.DisplayAlerts = False
myWb.SaveAs FileName:="D:\test\dump.xls"
Application.DisplayAlerts = True
myWb.Close False
Set myWb = Nothing
myExcel.Quit
Set myExcel = Nothing
End Sub
You can try:
On Error Resume Next
Set oExcel = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Err.Clear
Set oExcel = CreateObject("Excel.Application")
End If
On Error GoTo 0
oExcel.visible = true 'to check of excel opens
'try Set myWb = myExcel.Workbooks.Add()
'try Set myWb = oExcel.Workbooks.Open(sPathFile)

Finding last row throws an object required error

What I am trying to do.
I highlight some text in an email then run my macro.
It 'copies' the highlighted text and stores it in variable strText.
Then it creates a file called Artwork List.xlsx if it does not exist and if it exists it opens it.
After that it copies the text into the file in column A row 1 if the lastrow is 1, and if not, it appends to lastrow + 1
My code throws
'Run-time error 424, Object required'
To narrow down, the error should be coming from:
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
or anything related to this line.
Sub copyArts2File()
MsgBox "ok"
Dim OutApp As Object
Dim OutMail As Object
Dim olInsp As Object
Dim wdDoc As Object
Dim strText As String
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
Dim strTextArr As Variant
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
'Outlook wasn't running, so cancel
If Err <> 0 Then
MsgBox "Outlook is not running so nothing can be selected!"
GoTo lbl_Exit
End If
On Error GoTo 0
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = wdDoc.Application.Selection.Range.Text
End With
'MsgBox strText
lbl_Exit:
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
FileName = "Artwork List.xlsx"
fileDoesExist = Dir("C:\Users\quaer\Desktop\DL Arts\" & FileName) > ""
' Check for existing file
If fileDoesExist Then
' Open Excel file
Set xlBook = xlApp.Workbooks.Open("C:\Users\quaer\Desktop\DL Arts\" & FileName)
Set xlSheet = xlBook.Sheets(1)
Else
' Add Excel file
Set xlBook = xlApp.Workbooks.Add
With xlBook
.SaveAs FileName:="C:\Users\quaer\Desktop\DL Arts\" & FileName
End With
Set xlSheet = xlBook.Sheets(1)
End If
' Do stuff with Excel workbook
Dim i As Integer
Dim lastrow As Long
With xlApp
With xlBook
With xlSheet
strTextArr = Split(strText, "Adding file")
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
MsgBox lastrow
If lastrow = 1 Then
For i = 1 To UBound(strTextArr)
.Range("A" & i).Value = strTextArr(i)
Next i
Else
For i = 1 To UBound(strTextArr)
.Range("A" & (i + lastrow)).Value = strTextArr(i)
Next i
End If
.Close SaveChanges:=True
End With
End With
End With
xlApp.Visible = True
Exit Sub
End Sub
Try replacing this line, lastrow = .Cells(Rows.Count, 1).End(xlUp).Row, with:
lastrow = .Cells(1048576, 1).End(xlUp).Row
or
lastrow = .Cells(Rows.Count +1, 1).End(xlUp).Row
Jeeez this is crazy. I have found the problem finally and got a working code for anyone wanting similar usage. 1st off, I need to add the Microsoft excel add in. So in Outlook VBA, Tools -> references -> check Microsoft Excel 16.0 Object Library. This is to get rid of the 424 object required error, as I was trying to a call a excel built in method I guess. this is the line:
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
Pls note that I am calling this macro from Outlook.
After this I faced a couple of other issues.
1. errors such as 424 run time, remote server machine does not exist or is not available.
first time running, it throws this error, 2nd time I click, the problem goes away. This is an issue with non specific use of the app, book and worksheet and so leaves VBA to assign on its own. Lesson learnt, be explicit about every thing.
leaves a copy of excel process even after program ends. This can be seen in task manager. This causes issues because then my excel file is linked to this process and not able to open without either read only or notify. Its locked with the process. So I cannot run again next time.
Anyway. Here is the final code. And I have also changed it to .Range instead of .Cells. I believe it does not matter if I used either but the key culprit is : xlSheet.Rows.Count. Instead of just Rows.Count, explicitly use xlSheet.Rows.Count.
Option Explicit
Sub copyArts2File()
MsgBox "ok"
Dim OutApp As Object, OutMail As Object, olInsp As Object, wdDoc As Object
Dim xlApp As Excel.Application, xlBook As Excel.Workbook, xlSheet As Object
Dim strText As String
Dim strTextArr As Variant
Dim fName As String
Dim fileDoesExist As Boolean
Dim i As Integer
Dim lastrow As Long
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
'Outlook wasn't running, so cancel
If Err <> 0 Then
MsgBox "Outlook is not running so nothing can be selected!"
GoTo lbl_Exit
End If
On Error GoTo 0
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = wdDoc.Application.Selection.Range.Text
End With
'MsgBox strText
'Close out all shit
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
lbl_Exit:
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
On Error Resume Next 'Create or use a Excel Application
Set xlApp = GetObject(, "Excel.Application")
If Err.Number > 0 Then Set xlApp = CreateObject("Excel.Application")
On Error GoTo 0
xlApp.Visible = False
xlApp.DisplayAlerts = False
fName = "Artwork List.xlsx"
fileDoesExist = Dir("C:\Users\quaer\Desktop\DL Arts\" & fName) > ""
' Check for existing file
If fileDoesExist Then
' Open Excel file if present
Set xlBook = xlApp.Workbooks.Open("C:\Users\quaer\Desktop\DL Arts\" & fName)
Else
' Add Excel file if not present
Set xlBook = xlApp.Workbooks.Add
xlBook.SaveAs fileName:="C:\Users\quaer\Desktop\DL Arts\" & fName
End If
Set xlSheet = xlBook.Worksheets(1)
' Do stuff with Excel workbook
strTextArr = Split(strText, "Adding file")
lastrow = xlSheet.Range("A" & xlSheet.Rows.Count).End(xlUp).Row
If lastrow = 1 Then
For i = 1 To UBound(strTextArr)
xlSheet.Range("A" & i).Value = strTextArr(i)
Next i
Else
For i = 1 To UBound(strTextArr)
xlSheet.Range("A" & (i + lastrow)).Value = strTextArr(i)
Next i
End If
xlBook.SaveAs fileName:="C:\Users\quaer\Desktop\DL Arts\" & fName, AccessMode:=xlExclusive, ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges
xlBook.Close (True)
Set xlBook = Nothing
Set xlSheet = Nothing
xlApp.Visible = True
xlApp.Quit
Set xlApp = Nothing
MsgBox "Done!"
Exit Sub
End Sub
Thanks for the help and suggestions nonetheless.

Importing data from Access to Excel using Access VBA

I'd like to ask you for the help with the Access VBA code, that would import all the data from 1 specified query table from the Access database (currently open database) to MS Excel (the file, that could be selected by the user).
I'm currently having this piece of code, but I'm getting the error message saying:
"Run-time error '-2147023170 (800706be)':
Automation error The remote procedure call failed."
Would any of you know how to fix the connection?
Option Explicit
Option Compare Database
Public Sub CopyRstToExcel_test()
'On Error GoTo CopyRstToExcel_Err
Dim sPath As String
Dim fd As FileDialog
Dim oExcel As Object
Dim oExcelWrkBk As Object
Dim oExcelWrSht As Object
Dim dbs 'Added
Dim qdfName As String
Dim fRecords As Boolean
Dim rst As dao.Recordset
Dim iCols As Integer
'-------------------------------------------------------------------------------------------------------------------------------------------------------------------
' Select the file and identify the path leading to the file
'-------------------------------------------------------------------------------------------------------------------------------------------------------------------
'Define database you want to work with
Set dbs = CurrentDb
'Select the Excel file you want to work with
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'Define the path
If fd.Show = -1 Then
sPath = fd.SelectedItems(1)
End If
MsgBox sPath
'-------------------------------------------------------------------------------------------------------------------------------------------------------------------
' Defining names of variables
'-------------------------------------------------------------------------------------------------------------------------------------------------------------------
'Defining variables (queries/tables)
qdfName = "Query_1"
'------------------------------------------------------------------------------------------------
'Copying the data from Access into the new Excel
'------------------------------------------------------------------------------------------------
Set rst = CurrentDb.OpenRecordset(qdfName, dbOpenSnapshot)
fRecords = False
If rst.EOF = False Then
fRecords = True
Set oExcel = CreateObject("Excel.Application")
Set oExcelWrkBk = GetObject(sPath)
oExcel.Visible = True
oExcel.ScreenUpdating = False
Set oExcelWrSht = oExcelWrkBk.Sheets(1)
For iCols = 0 To rst.Fields.Count - 1
oExcelWrSht.Cells(9, iCols + 2).Value = rst.Fields(iCols).Name
Next
oExcelWrSht.Range(oExcelWrSht.Cells(9, 2), _
oExcelWrSht.Cells(9, rst.Fields.Count)).Font.Bold = True
oExcelWrSht.Range("B10").CopyFromRecordset rst
oExcelWrSht.Range(oExcelWrSht.Cells(9, 2), _
oExcelWrSht.Cells(rst.RecordCount + 9, rst.Fields.Count)).Columns.AutoFit
oExcelWrSht.Range("A1").Select
End If
'------------------------------------------------------------------------------------------------
CopyRstToExcel_Done:
On Error Resume Next
If fRecords = True Then
oExcel.Visible = True
oExcel.ScreenUpdating = True
End If
Set oExcelWrSht = Nothing
Set oExcelWrkBk = Nothing
Set oExcel = Nothing
Set rst = Nothing
''Error message:
'CopyRstToExcel_Err:
' MsgBox Err & ": " & Error, vbExclamation
' Resume CopyRstToExcel_Done
' Resume
'------------------------------------------------------------------------------------------------
End Sub
In this step, I only want to copy the data in the first sheet, but later on I would also like to specify the name of the sheet and I've got already prepared templates I want to copy the data over.
Thank you for your help!
Try to replace
Set oExcelWrkBk = GetObject(sPath)
by
Set oExcelWrkBk = oExcel.Workbooks.Open(sPath)
Also I'd recommend to replace
Set rst = CurrentDb.OpenRecordset(qdfName, dbOpenSnapshot)
by
Set rst = dbs.OpenRecordset(qdfName, dbOpenSnapshot)
Open specified worksheet:
Set oExcelWrSht = oExcelWrkBk.Sheets("MyWorksheetName")

Word report automation sourcing numbers from Excel

I need to automate reporting in word by extracting numbers from Excel. I searched and followed the code sourced from http://www.makeuseof.com/tag/integrate-excel-data-word-document/
Code doesn't run properly and encounters a number of errors.
1. Excel doesn't open
2. Encounter Run-time error '438': Object doesn't support this property or method.
I have used the "early binding" code suggested by website and doesn't work and the researched to use "late binding". still doesn't work. I inserted "Microsoft Excel 14.0 Object Library" and insert "Label" in word doc under "ActiveX Control"
Don't know what went wrong.
Current vba code
Private Sub CommandButton1_Click()
Dim objExcel As Object
Set objExcel = CreateObject("Excel.Application")
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
ThisDocument.DMY.Caption = exWb.Sheets("Summary").Cell(5, 4)
exWb.Close
Set exWb = Nothing
End Sub
Previous code
Private Sub CommandButton1_Click()
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
ThisDocument.DMY.Caption = exWb.Sheets("Summary").Cells(5, 4)
exWb.Close
Set exWb = Nothing
End Sub
Adapting code from: https://www.experts-exchange.com/questions/26874253/How-to-loop-with-VBA-on-all-controls-placed-in-a-Word-doc.html
You can write a utility function to get an ActiveX control given its name and the hosting document:
Private Sub CommandButton1_Click()
Dim con As Object
Dim objExcel As Object, exWb As Object
Set con = ActiveXControlByName(ThisDocument, "DMY")
If Not con Is Nothing Then
Set objExcel = CreateObject("Excel.Application")
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
con.Caption = exWb.Sheets("Summary").Cell(5, 4).Value
exWb.Close False
Set exWb = Nothing
objExcel.Quit
End If
End Sub
Function ActiveXControlByName(doc As Document, theName As String) As Object
Dim ilsh As InlineShape
Dim sh As Shape, ob As Object
For Each ilsh In doc.InlineShapes
If ilsh.Type = wdInlineShapeOLEControlObject Then
Set ob = ilsh.OLEFormat.Object
If ob.Name = theName Then
Set ActiveXControlByName = ob
Exit Function
End If
End If
Next ilsh
For Each sh In ActiveDocument.Shapes
If sh.Type = msoOLEControlObject Then
Set ob = sh.OLEFormat.Object
If ob.Name = theName Then
Set ActiveXControlByName = ob
Exit Function
End If
End If
Next sh
'if got here then control was not found...
Set ActiveXControlByName = Nothing
End Function

How to copy value from a cell in MSExcel into a field in MSWord file with VB Code?

I need to have a vb code in ms word 2003 that copy a a specific cell in excel file and paste it in word (filed). Below is what I have done and it result in error.
Sub cmdGetNumber()
Dim XL As Object
Dim WBEx As Object
Dim ExelWS As Object
Dim appwd As Object
Dim wdApp As Word.Application
''''
'On Error GoTo OLE_ERROR
Set XL = CreateObject("Excel.Application")
Set wdApp = CreateObject("Word.Application")
'Open Excel document
Set WBEx = XL.Workbooks.Open("C:\Documents and Settings\121567\Desktop\tafket1.xls")
Set ExelWS = WBEx.Worksheets("Sheet1")
XL.Visible = True
'appwd.Visible = True
ExelWS.Range("c2").Select
'Selection.Copy
'wdApp.Selection.PasteSpecial Placement:=wdInLine, DataType:=wdPasteMetafilePicture
'wdApp.Documents.Save
Set wdApp = Nothing
Set ExelWS = Nothing
Set WBEx = Nothing
End Sub
Since this macro is in Word, you don't need to explicitly open a word instance. You can just do Documents.Add to add a new document, or Documents.Open to open an existing one.
Try this:
Sub cmdGetNumber()
Dim XL As Object
Dim WBEx As Object
Dim ExelWS As Object
Dim wdDoc As Word.Document
'On Error GoTo OLE_ERROR
Set XL = CreateObject("Excel.Application")
'Open Excel document
Set WBEx = XL.Workbooks.Open("C:\Documents and Settings\121567\Desktop\tafket1.xls")
Set ExelWS = WBEx.Worksheets("Sheet1")
'XL.Visible = True
ExelWS.Range("C2").Copy
Set wdDoc = Documents.Add
wdDoc.Activate
wdDoc.Select
Selection.Paste
WBEx.Close
XL.Quit
Set WBEx = Nothing
Set ExelWS = Nothing
Set XL = Nothing
End Sub
The above code will open your excel file, copy the cell C2, then open a new word document, and paste it there.
I see you have mentioned a (filed) in your question. Did you mean a Field or a File? If it is a Field then you may want to replace Selection.Paste with the relevant field name

Resources