I'm writing contents of tables from access to excel(Opening the excel file from access) After writing it i'm trying to save all workbooks in the appXL application. For that i'm making DispalyAlerts false before saving and trun on back after saving. After writing contents to excel i'm closing the access. After writing ,when i'm trying to close the excel, it is not giving any alerts like Do you want to save the contents?
My vba code
Sub Writexl()
Dim appXL As Excel.Application
Dim wb As Excel.Workbook
StrwbPath="C:\temp\sample.xls"
Set appXL = CreateObject("Excel.Application")
With appXL
Set wb = .Workbooks.Open(StrwbPath)
.Visible = True
End With
'here code for writing contents
'save workbook after writing
appXL.Application.DisplayAlerts = False
For Each w In appXL.Application.Workbooks
w.Save
Next w
appXL.Application.DisplayAlerts = True
DoCmd.Quit acQuitSaveAll
Application.Quit
End sub
You are setting the DisplayAlerts to the Application's Applicaiton
appXL.Application.DisplayAlerts = True
is conceptually equivalent to
Excel.Application.Application.DisplayAlerts = True
So the property is being set on the parent application to Excel.
Try
appXL.DisplayAlerts = True
After writing ,when i'm trying to close the excel, it is not giving
any alerts like Do you want to save the contents?
As #David Zemens says, why would it display a message to save all changes when you've already saved everything. Have you tried changing a cell and then exiting Excel?
Related
I currently have a Microsoft Access Database (file format is 2007-2016) that we use to track open orders and print all the required documents. I have created a word document that pulls information from this database using MailMerge. This document works flawlessly by itself. Meaning that if I actually double click the document it opens correctly asking me if I want to pull the information from the database. The issue is that if I open it via a command button in the database I the document opens but I will not get the MailMerge dialog asking if I want to pull the information.
Here is the code I am using at the moment to open the document.
Private Sub Print_Click()
If IsNull(Me.DateShipped.Value) Then
Me.DateShipped = Date
End If
DoCmd.RunCommand acCmdSaveRecord
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Open("F:\Database\merge\INDIVIDUAL.docx")
Set wrdApp = Nothing
Set wrdDoc = Nothing
DoCmd.RunCommand acCmdSaveRecord
Any help will be appreciated.
Thank you
Joel
What is the simplest VBA code I could put in an access form button that will export a field value to a specified cell in excel?
Please do search before submitting a question in StackOverflow. There a multiple answers to this question and you did not include sufficient background too.
Is your Excel open?
Is your Excel even created?
I
I'll attach the code to create a new instance of Excel, and write text to a specific cell.
Private Sub Button_Click()
Dim objExcel As Excel.Application
Dim objSheet As Excel.Workbook
Set objExcel = New Excel.Application
Set objSheet = objExcel.Workbooks.Open("C:\MyExcelfile.xlsx")
objExcel.Range("C6").Value = "Some text to write here"
objExcel.Range("D7").Value = me.textboxSomething.value
objSheet.save
Set objSheet = Nothing
objExcel.Quit
Set objExcel = Nothing
End sub
You have to deal with error handling in case of error.
Do note you have to add "Microsoft Excel 1#.0 Object library" reference, in your access vba editor, under tools menu.
(Currently using Access 2003) Within my project I have a subform, frmSub, that holds the results of a query, located within a form (frmMain).
frmSub is a subform control which contains a query instead of a form (its SourceObject property is set to "Query.qrySearch")
Using various run time counters, the query orders the results with the 'best' at top. The user can then manually select down which ever results they require, or take all the results.
What I'd like to do is provide a way to open the results in Excel (either the user selection or all the results if no selection is made). Ignoring the likely more frequently used 'create temp export .xls file' method for the now, I'm currently looking at a copy/paste method, mimiking the ctl-C/V way the user currently uses.
I have placed an ‘Open in Excel’ button in frmMain.
In the frmSub's Exit event I look at .SelHeight, returning >0 if a selection is made…
If Me.frmSub.Form.SelHeight > 0 Then
DoCmd.RunCommand acCmdCopy
Else:
DoCmd.RunCommand acCmdSelectAllRecords
DoCmd.RunCommand acCmdCopy
End If
Behind the ‘Open in Excel’ button on frmMain I have…
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
With xlApp
.Workbooks.Add
.ActiveSheet.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
.Cells.Select
.Cells.EntireColumn.AutoFit
.Visible = True
.Range("a1").Select
End With
Set xlApp = Nothing
Call EmptyClipboard
Call EmptyClipboard calls an api based routine that clears the clipboard.
While I realise that using the clipboard this way is likely not best practice, I’m not sure if that thought is universal if a reasonable use could be identified (It’s not expected that the user would be particularly disadvantaged here)
Problem
While the above works well there are issues with using the Exit event since it fires not only on clicking the ‘Exit to Excel’ button – and an Export to Excel, here, causes issues if the clipboard is empty.
Is there a way to determine if it was the ‘Exit to Excel’ button that initiated the sub form’s Exit event – and trap this in that the Exit event’s code? The only events I seem to have access to in frmSub is On Exit and On Enter.
If any copy/paste method would likely remain problematic then I could look at exporting to a tmp .xls file.
With some more time to work on this I’ve rearranged things, I think, for the better. In particular, the Exit event is now only used to store the datasheet’s selection parameters, thus shifting the Copy stage into the ‘Export to Excel’ button…
frmSub Exit event includes…
tmpSelHeight = Me.frmSub.Form.SelHeight
tmpSelTop = Me.frmSub.Form.SelTop
tmpSelLeft = Me.frmSub.Form.SelLeft
tmpSelWidth = Me.frmSub.Form.SelWidth
Behind the ‘Open in Excel’ button on frmMain there is now included…
If IsProcessRunning("excel.exe") Then
If MsgBox("Excel is currently running: click Yes to view in new Excel instance", vbYesNo, "") = vbNo Then Exit Sub
End If
If tmpSelHeight > 0 Then
Form! frmSub.SetFocus
Me. frmSub.Form.SelHeight = tmpSelHeight
Me. frmSub.Form.SelTop = tmpSelTop
Me. frmSub.Form.SelLeft = tmpSelLeft
Me. frmSub.Form.SelWidth = tmpSelWidth
DoCmd.RunCommand acCmdCopy
Else
Form! frmSub.SetFocus
DoCmd.RunCommand acCmdSelectAllRecords
DoCmd.RunCommand acCmdCopy
End If
Me. frmSub.Form.SelHeight = 0
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
With xlApp
.Visible = True
.Workbooks.Add
.ActiveSheet.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
.Cells.Select
.Cells.EntireColumn.AutoFit
.Range("a1").Select
End With
Set xlApp = Nothing
Call EmptyClipboard
AppActivate "Microsoft Excel"
While things appear stable enough…
I’m still manipulating the clipboard though this is not expected to be an issue.
I could later look at using any existing Excel instance.
I could still consider exporting to a .xls file, or store in temp table & linking table to Excel, as alternative methods.
I have a macro (created with the macro wizard) which runs a number of queries and then outputs a table to excel. The table has more then the 65,000 records limit for exporting formatted tables. How can I export the table without formatting in the macro? Here is the error I receive after I run the macro.
I know you are using access vba to export the records but have you thought about using a datalink to your query from excel and using the access vba to open the excel file and refresh the data table? this will definitely eliminate any issues with max rows and should not have any failure issues due to export size. If you need more info on how to do that let me know and I'll add more info here.
Here is the code requested by Anthony Griggs above. But it is a VBA solution, not a macro solution, so not directly responsive to the question as posted. This was how I worked around the problem and have had this successfully in production for a long time.
Be sure to add the reference to "Microsoft ActiveX Data Objects 2.8 Library" (or current version for you) and also the "Microsoft Excel 12.0 Object Library" (or current version for you) before using this code. The save changes and quit at the end are critical, otherwise it leaves Excel open in the background that you have to kill via task manager.
Dim rs As New ADODB.Recordset
Dim xl As New Excel.Application
Dim xlWb As Excel.Workbook
Dim xlRange As Excel.Range
xl.Visible = False
xl.ScreenUpdating = False
vcurfilename = "MyFilename.XLSX”
Set xlWb = xl.Workbooks.Open(vcurfilename, 0, False, 5, "password", "password")
rs.Open "Select * from qryMyAccessQuery", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
Set xlRange = xlWb.Worksheets("MyExcelSheetName").Range("A1").Offset(1, 0)
xlWb.Sheets("MyExcelSheetName ").Range("a2:bq25000").ClearContents
xlRange.Cells.CopyFromRecordset rs
xl.Range("Table1").Sort key1:=xl.Range("Table1[[#All],[MyColumnName]]"), _
order1:=xlAscending, Header:=xlYes
On Error Resume Next
xl.Range("table1").Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0
rs.Close
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName1").EntireColumn.NumberFormat = "dd-MMM-yy"
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName2").EntireColumn.NumberFormat = "dd-MMM-yy"
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName3").EntireColumn.NumberFormat = "dd-MMM-yy"
xlWb.Close SaveChanges:=True
xl.Quit
DoEvents
I have a table in MS Access, which has the following data to be exported to excel
Release numbers
Test cases
Results
After exporting to Excel I want to have distinct release numbers as rows starting from A2 and distinct test case name as columns starting from B1. There might be couple thousands records. Then each cell will be set to result tag. Additionally will need some fancy coloring/bordering stuff.
The question - is it possible to do this using VBA in Access and if yes what is the way to go? Any hint, sample, example, resource would be appreciated... I've googled but the most thing I came accross is DoCmd.TransferSpreadsheet or DoCmd.OutputTo which I believe will not do what I want. Saw some examples with CreateObject("Excel.Application") but not sure what are limitations and performance using this way.
I don't know if it would work for your case, but you might try adding the VBA code to an Excel document rather than the Access database. Then you could refresh the data from the Excel file and add the formatting there much easier. Here is one example:
http://www.exceltip.com/st/Import_data_from_Access_to_Excel_%28ADO%29_using_VBA_in_Microsoft_Excel/427.html
(Or see other examples at http://www.exceltip.com/exceltips.php?view=category&ID=213)
Again, it may not work for your case, but it may be an option to consider. Essentially, instead of pushing from Access, you would pull from Excel.
Yes, there are many cases when the DoCmd.TransferSpreadsheet command is inadaquate.
The easiest way is to reference the Excel xx.x Object model within Access (Early Binding). Create and test your vba export function that way. Then once you are satisfied with your output, remove the Excel object model reference, then change your objects to use use Late Binding using CreateObject. This allows you to easily have other machines that are using different versions of Excel/Access to use it just the same.
Here is a quick example:
Sub ExportRecordsetToExcel(outputPath As String, rs As ADODB.Recordset)
'exports the past due report in correct formattig to the specified path
On Error GoTo handler:
Const xlUP As Long = -4162 'excel constants if used need to be referenced manually!
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Dim row As Long
If rs.BOF And rs.EOF Then
Exit Sub 'no data to write
Else
rs.MoveFirst
End If
row = 1
Set oExcel = CreateObject("Excel.Application")
oExcel.Visible = False 'toggle for debugging
Set oBook = oExcel.Workbooks.Add 'default workbook has 3 sheets
'Add data to cells of the first worksheet in the new workbook.
Set oSheet = oBook.worksheets(1)
Do While rs.EOF = False
oSheet.range("A" & row).value = rs.Fields("MyField").value
'increase row
row = row + 1
Loop
oBook.SaveAs (outputPath)
'tidy up, dont leave open excel process
Set oSheet = Nothing
Set oBook = Nothing
oExcel.Quit
Set oExcel = Nothing
Exit Sub
handler:
'clean up all objects to not leave hanging processes
End Sub