Access query to excel 2010 to create a graph via vba - ms-access

After an extensive search I have been unable to find any information on this that I could understand. there are numerous examples, but these are all for access 2003, and these do not work in access 2010.
I need to run a vba code that will export the results of a query (QryTotalSale) to excel 2010 and automatically create a bar chart of the data and show this over the database that is running.
If anyone could give me some advise then I would greatly appreciate it, or even a link to a valid resource that will work in 2010.
So far I can get excel to open, and display the results of the query in question.
To make it more difficult I really need the query to open a specific excel file, which will be on a folder on the desktop and every time the button is pressed to run the VBA, a new page should be added to the excel workbook, and the new graph be shown, and saved into the spreadsheet, so that at a later date the entire excel file can be viewed.
I have the below code, but it does not work. the bit about ranges would work in excel, but access does not seem to recognise range ( which does not really suprise me as it does not really work with ranges to my knowledge.)
My second thought was to have the first two doCmd's run, then have the next bit be forced to auto run in the excel file.
Private Sub SalesImage_Click()
DoCmd.OpenQuery "QryTotalSale"
DoCmd.RunCommand acCmdOutputToExcel
Dim myRange as range
Set myRange = B2 * C30
Charts.Add
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=myRange, _
PlotBy:=xlColumns
ActiveChart.Location Where:=xlLocationAsNewSheet
End Sub
I found a adodb code type thing for the 2003 versions of access and excel, but could not get this to work. half of the options no longer seem to be recognised by access...
I am a long way off and would really appreciate any help.
Thanks
Sam

Here are some notes. I have used late binding, so you do not need to set a reference to the Excel library, however, I have included notes on the types.
Dim xl As Object ''Excel.Application
Dim wb As Object ''Excel.Workbook
Dim ws As Object ''Excel.Worksheet
Dim ch As Object ''Excel.Chart
Dim myRange As Object
Set xl = CreateObject("Excel.Application")
sExcelWB = "z:\docs\testchart.xls"
''This will overwrite any previous run of this query to this workbook
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "Query1", _
sExcelWB, True
Set wb = xl.Workbooks.Open(sExcelWB)
''Sheets are named with the Access query name
Set ws = wb.Sheets("Query1")
Set ch = xl.Charts.Add
ch.ChartType = xlColumnClustered
xl.Visible = True
xl.UserControl = True
''Still not saved

Related

VBA Alternatives to workbook.open to pull data from a single cell

I wanted to find out if anyone can recommend an alternative way to query data in an excel file from an MS Access module.
If I have a data organised in a typical "Table" format e.g rows and columns with headers, then I have been connecting to the workbook using a DAO connection as below
Dim db as DAO.Database
Dim rsUsers as DAO.Recordset
Set db = OpenDatabase("C:\SaleLog.xls", False, True, "Excel 8.0;HDR=Yes;")
Set rsUsers = db.OpenRecordset("SELECT userID FROM [Sales$]")
I find this preferable to using
Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Open "C:\SaleLog.xls", True, False
As it does not physically open an instance of an excel session and therefore runs a bit more quickly.
The only problem is when the data is not laid out like a table (e.g if I just wanted to get the value of 1 particular cell).
Does anyone know if there is a way to check the value of a cell in VBA without using Workbook.Open?
There may be a simpler way to achieve this but I have found 3 methods which can be used to pull data into MS Access from a single cell in a closed Excel workbook relatively efficiently (Many thanks to John Muggins for his help with this).
Firstly, the workbooks.open method can be used and will run more quickly if you set the read-only parameter to true (I'm unsure if this technically 'Opens' the workbook but it definitely seems to run more quickly while read-only). This requires you to set a reference to the Excel library.
Dim xlApp As Excel.Application
Dim src As Workbook
Set xlApp = CreateObject("Excel.Application")
Set src = xlApp.Workbooks.Open "C:\SaleLog.xls", True, True
You can then get data from specific cells using normal Excel VBA syntax like so
strUser = src.Worksheets("Sales").Range("B8")
src.Close False 'false doesn't save changes
Set src = Nothing
Another method is to use the DoCmd.Transferspreadsheet method to link or import a single cell, in this case you would need to set the HasFieldNames parameter to false as shown
path = "C:\SaleLog.xls"
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "tblTemp", path, False, "Sales!B8:B8"
This will create a table with a single field called F1. You can get the value stored in this table using a DLookup or a recordset (You may then wish to delete the temp table e.g. DoCmd.DeleteObject acTable, "tblTemp").
Lastly you can use a DAO connection as mentioned in the original question. You can specify a specific cell like so
Dim db as DAO.Database
Dim rsUsers as DAO.Recordset
Set db = OpenDatabase("C:\SaleLog.xls", False, True, "Excel 8.0;HDR=Yes;")
Set rsUsers = db.OpenRecordset("SELECT * FROM [Sales$B8:B8]")
Again this will create a recordset with a single field called F1. You can get the value of this field by using rsUsers.Fields("F1")
Each of the above methods can be (and usually are) used to pull data from an entire worksheet or range of cells but for the purpose of this question I wanted to show how they can be used to pull data from a single cell. I haven't tested them for efficiency although I doubt there is much difference in speed between them so probably best to go with the method that you find simplest.
If anyone knows how to tweak any of these methods to make them more efficient or has another approach altogether please feel free to comment or add a new answer :)

How do I create copies of CurrentDb using VBA

I need to create copies of the CurrentDB using VBA (approx. 12 copies). The copies need to be clones of the master database containing all the same forms, queries, etc. except only a limited dataset.
DoCmd.CopyDatabaseFile seems to be made for this, but only works if you are using it to copy the DB to an MS SQL Server. As MS states on their website:
Copies the database connected to the current project to a Microsoft
SQL Server database file for export.
docmd.TransferDatabase only exports the data itself, but not the structure, forms, etc.
Code I have found on the web and adapted doesn't work and throws an error on the .CopyFile line saying:
Run-time error 52: Bad file name or number
This is the code
Sub CopyDB()
Dim external_db As Object
Dim sDBsource As String
Dim sDBdest As String
sDBsource = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting.accdb"
sDBdest = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting_2.accdb"""
Set external_db = CreateObject("Scripting.FileSystemObject")
external_db.CopyFile sDBsource, sDBdest, True
Set external_db = Nothing
End Sub
How can I fix the above line? Alternatively is there a direct command in Access to create a copy? The "create backup" function would be tailor made for this, but I can not find it in VBA.
Looks like you have an extra quote in sDBdest accdb"""
And for database copy you can also use
FileCopy sDBsource, sDBdest
Instead of Scripting object

MS Access macro for exporting to Excel hits limit of 65k records

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

VBS file only works when double-clicked

I am trying to use the Windows 8 Location API in order to get GPS coordinates from a built-in sensor, and return these coordinates to MS Access. However, due to the unsupported variant types used in the API, Access is unable to reliably use its objects. I am trying to come up with a workaround using a VBScript file, and somehow returning the values to MS Access (using 2010 and 2013). The easiest way I could think of was to spit out a txt file to be read by Access and then deleted.
My VBS File works perfectly when I run it from Windows Explorer (double-clicking the file) but I can't find a way to make it work properly when running it from VBA code. Here is the VBS File:
Dim latlongfactory
Dim rptLong, rptLat
Dim report
Dim keepSleeping
Dim fs, f
Dim ts
Set latlongfactory = Wscript.CreateObject("LocationDisp.LatLongReportFactory", "llf_")
Set fs = Wscript.CreateObject("Scripting.FileSystemObject")
f = fs.BuildPath(CurrentDirectory, "gpsTempFile.txt")
keepSleeping = True
latlongfactory.ListenForReports(1000)
Sub llf_NewLatLongReport(report)
rptLong = report.Longitude
rptLat = report.Latitude
keepSleeping = False
End Sub
Do While keepSleeping
Wscript.Sleep(20)
Loop
Set ts = fs.CreateTextFile(f, True)
ts.WriteLine rptLat & "," & rptLong
ts.Close
Set fs = Nothing
Set latlongfactory = Nothing
set report = Nothing
When run through VBA, it doesn't create the text file anymore, and I'm not entirely sure why. I tried adding a Msgbox at the end of the script just to see if the code was running. The Msgbox does come up.
The line I use to execute in Access VBA is:
Shell "Wscript """ & CurrentProject.Path & "\gpscoordinates.vbs""", 1
It runs the VBS file, but the text file isn't getting created and I cannot figure out why. Any help would be much appreciated!
If you want the output file to be created in the same folder in which the script resides, you can use the ScriptFullName property of the WScript object:
outputFolder = fs.GetParentFolderName(WScript.ScriptFullName)
f = fs.BuildPath(outputFolder, "gpsTempFile.txt")

Exporting data from MS Access to Excel using VBA

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