I have an MS access 2010 database which is connected to a MS Excel 2010 for reporting purpose. I have linked the Excel to Access using Get External Data option in excel. With few changes in the reporting requirements I had to create a new query in Access (and it has some custom function). The Custom Function is a VBA module in Access.
Unfortunately when I use the Get External Data in Excel to link my new access query, the new query (View) is not listed on the list of Table/View (Import Wizard). When I remove the Custom Function the query is displayed in the wizard.
My Custom Function to Concatenate rows (taken from another site)
Public Function ConcatADO(strSQL As String, strColDelim, _
strRowDelim, ParamArray NameList() As Variant)
Dim rs As New ADODB.Recordset
Dim strList As String
On Error GoTo Proc_Err
If strSQL <> "" Then
rs.Open strSQL, CurrentProject.Connection
strList = rs.GetString(, , strColDelim, strRowDelim)
strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
Else
strList = Join(NameList, strColDelim)
End If
ConcatADO = strList
Exit Function
Proc_Err:
ConcatADO = "***" & UCase(Err.Description)
End Function
and following is the JET SQL used in the new query (which works absolutely fine within Access)
SELECT DISTINCT
D.[Ref ID],
D.[ENTRYDATE],
D.[AUDITOR LID],
D.[Process],
D.[Auditee],
D.[Auditee Name],
D.[Account No],
D.[Auditee Manager],
D.[MaxScore],
D.[Score],
D.[Result],
ConcatADO("SELECT [COMMENTS] FROM ycube WHERE [Ref ID]=" & "'" & [d].[Ref ID] & "'" ,", "," : ") AS [Master Comment]
FROM ycube AS D;
Is it the limitation of Excel when we use Custom Function and
Is there a way around to import (rather link) above Access query to Excel
Related
Working in Access 2010 against an Access DB, I created a query in the QBE. As part of an overly complex quarterly reporting process, I now need to be able to execute that query with different parameters via VBA code. The SQL for the query is now embedded in my VBA module, and is modified on the fly, then executed. When run in the QBE, this particular instance of the query returns 400+ rows of data, but none are returned when executed in VBA via this code:
Dim Data As New ADODB.Recordset
Dim SQLString As String
SQLString = "SELECT PatientStatSchedDataDump.PtCompID, AppType.ProviderW, " & _
"PatientStatSchedDataDump.Date, PatientStatSchedDataDump.Status " & _
"FROM (AppType INNER JOIN PatientStatSchedDataDump ON AppType.AType = " & _
"PatientStatSchedDataDump.Type) LEFT JOIN GroupType ON AppType.Group = " & _
"GroupType.Group " & _
"WHERE (((PatientStatSchedDataDump.PtCompID) Like 'ClientName*' ) " & _
"AND ((PatientStatSchedDataDump.Date) BETWEEN #1/1/2014# AND #3/31/2014#) " & _
"AND ((GroupType.[Sort Order]) IN ('A', 'B', 'C', 'D', 'E')))"
Data.Open Source:=SQLString, ActiveConnection:=CurrentProject.Connection
If Not Data.EOF And Not Data.BOF Then
'the IF is never true - EOF & BOF are always True
NewSheet.Cells(InstCountRow + InstCount + 2, 1).CopyFromRecordset Data
End If
Data.Close
Set Data = Nothing
Again, if I create a new query in Access, paste the SQL code into the SQL window and run it, I get 400+ rows of results with this exact query
A query run from ADO requires ANSI wild cards: % instead of *; and _ instead of ?.
So change this ...
"WHERE (((PatientStatSchedDataDump.PtCompID) Like 'ClientName*' ) "
to this ...
"WHERE (((PatientStatSchedDataDump.PtCompID) Like 'ClientName%' ) "
If you want one query which works the same when run from ADO as it does when run in the QBE, you can use ALike instead of Like. With ALike, the db engine always expects ANSI wildcards.
"WHERE (((PatientStatSchedDataDump.PtCompID) ALike 'ClientName%' ) "
Good Afternoon,
I have an access query that contains a list of all my customers lets call that CUS
I have another query that has a list of ORDERS
I would like to write some VBS that cycles through the customer list and exports a csv file containing all orders that belong to that customer.
The vba would then move on to the next customer on the list and perform the same action.
Any help would be great.
Snippet of code below
almost there cant get the WHERE condition working it keeps displaying a popup for me to populate however the same string is feeding the msgbox fine here is a snippet below tht is within the loop
strcustcode = rs!OCUSTCODE
ordercount = rs!orders
TIMEFILE = Format$(Time, "HHMM")
MsgBox ([strcustcode] & " has " & [ordercount] & " orders")
StrSQL = "Select * From [24-ND_Cus] where [24-ND_Cus].[OCUSTCODE] = strcustcode "
Set qd = db.CreateQueryDef("tmpExport", StrSQL)
DoCmd.TransferText acExportDelim, , "tmpExport", "c:file.csv" db.QueryDefs.Delete "tmpExport" –
Don't use [ ] around VBA variables. Don't use parens for the MsgBox when you just want to give user a message. The parens make it a function that requires a response by user to set a variable.
MsgBox strcustcode & " has " & ordercount & " orders"
Concatenate the variable into the SQL statement. If OCUSTCODE is a text type field, use apostrophe delimiters for the parameter.
StrSQL = "Select * From [24-ND_Cus] Where [OCUSTCODE] = '" & strcustcode & "'"
I don't advise code that routinely modifies design and changing a query SQL statement is changing design. If the only change is filter criteria and a dynamic parameterized query won't work, I suggest a 'temp' table - table is permanent, data is temporary. Delete and write records to the table and export the table.
I am stymied by an SQL mediated import of a CSV file using VBA code. I am using a Third EXCEL macro/spreadsheet, to analyze a LEFT JOIN of 2 files, one as an XLXS and the other as a CSV.
I suspect that part of the problem may be how the SQL command is used, for a FROM reference to an excel file. I am using Excel VBA, 2010, The 14 Database Access Engine.
I want to end with an SQL statement that pulls from an external comma delimited CSV file
I anticipate heading the macro with this pseudo code, in a stand-alone macro enabled excel file:
dbEngine = CreateObject(DAO.engine ... )
set DB = dbEngine.OpenDatabase(theNormalExternalExcellFile,....)
For the SQL statement, in pseudo-code, I want this:
SELECT fields
FROM [Table$] ' a normal external excel file
LEFT JOIN [an external CSV, comma delimited file]
ON...
GROUP...
I can successfully import an XLXS, or the CSV, independently, in a simple SQL statement, yet when I place the outside file references within an SQL's FROM clause, I get one of two errors, depending on how I play with the code: an Invalid File Path, or an error in the FROM Clause. The path is -not- invalid.
The error is shown, below, where it occurs, at the recordset instruction.
I also provide alternative SQL strings, which I had played with to test where in the code the error is generated.
'the Seating Chart
strPathSource = ThisWorkbook.Worksheets("Logic").Range("rngPathSource")
'strFileNameSource = ThisWorkbook.Worksheets("Logic").Range("rngFileNameSource")
'strFileNameSourceWOExt = Left(strFileNameSource, Len(strFileNameSource) - 4)
'the attendance
strPathAttendance = ThisWorkbook.Worksheets("Logic").Range("rngPathAttendance")
strFileNameAttendance = ThisWorkbook.Worksheets("Logic").Range("rngFileNameAttendance")
strFolderAttendance = ThisWorkbook.Worksheets("Logic").Range("rngFolderAttendance")
strFileNameAttendanceWOExt = Left(strFileNameAttendance, Len(strFileNameAttendance) - 4)
Set dbE = CreateObject("Dao.DBEngine.120")
Set db = dbe.OpenDatabase(strPathSource, True, False, "Excel 12.0;HDR=Yes")
''Set db = DAO.OpenDatabase(strFolderAttendance, True, False, "text;HDR=Yes;FMT=Delimited(,)")
'[Master$] is a tab on the spreadsheet at strPathSource
'[Attendance#csv]
' This reference to the table at strPathAttendance which otherwise works: [Attendance#csv]
' when not inside the FROM clause
strSQL = _
"SELECT tM.Job, Count(tA.Name) AS CountOfName" _
& " FROM [Master$] tM" _
& " LEFT JOIN" _
& " (SELECT * FROM [text;HDR=Yes;FMT=Delimited(,);Database='" _
& strPathAttendance & "'].[" & strFileNameAttendanceWOExt & "#csv]) tA" _
& " ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)" _
& " GROUP BY tM.Job" _
& " ORDER BY tM.Job, Count(tA.Name)"
'Debug.Print strSQL
' This is the reported value for the string, strSQL, particularly the FROM clause:
' SELECT tM.Job, Count(tA.Name) AS CountOfName FROM [Master$] tM LEFT JOIN
' (SELECT * FROM
' [text;HDR=Yes;FMT=Delimited(,);Database=T:\Solutions Team Shared Folder\Seats -
' Attendance\Attendance.csv].[Attendance#csv]) tA
' ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)
' GROUP BY tM.Job ORDER BY tM.Job, Count(tA.Name)
'' putting a single or double quote, around the database path, does not change the error
Set rstR = db.OpenRecordset(strSQL)
'Error:
' 'T:\...\...\Attendance.csv' is not a valid path. Make sure that
' the path name is spelled correctly and that you are connected to the server
' on which the file resides.
' ALT SQL strings, to test what's going on.
'strSQL = _
' "Select * FROM [Attendance#csv]"
'strSQL = _
' "Select * FROM (Select * FROM [Excel 12.0;HDR=Yes;Database=" & strPathSource & "].[Master$])"
'strSQL = _
' "SELECT * FROM [text;HDR=Yes;FMT=Delimited(,);Database=" _
' & strPathAttendance & "].[" & strFileNameAttendanceWOExt & "#csv]"
'strSQL = _
' "Select * FROM [Excel 12.0;HDR=Yes;Database=" & strPathSource & "].[Master$]"
When connected to text files with Jet/ACE SQL, the database parameter needs to reference the directory path not any specific text file. The period qualifier will then specify the individual file.
Therefore, simply remove the file name and extension from strPathAttendance (without quotes). So query should look like the below:
SELECT tM.Job, Count(tA.Name) AS CountOfName
FROM [Master$] tM
LEFT JOIN
(SELECT * FROM
[text;HDR=Yes;FMT=Delimited(,);Database=T:\Solutions Team Shared Folder\Seats -
Attendance].[Attendance#csv]) tA
ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)
GROUP BY tM.Job
ORDER BY tM.Job, Count(tA.Name)
I have an Excel Spreadsheet that calculates a risk (of perioperative mortality after aneurysm repair) based on various test results.
The user inputs the test results into the spreadsheet (into cells) and then out comes a set of figures (about 6 results) for the various models that predict mortality. The spreadsheet acts as a complex function to produce the results one patient at a time.
I also have a (separate) access database holding data on multiple patients - including all the data on test results that go into the spreadsheet. At the moment I have to manually input this data into the spreadsheet, get the results out and then manually enter them onto the database.
Is there a way of doing this automatically. Ie can I export data1, data2, data3... from Access into the spreadsheet to the cells where the data needs to be input and then get the results (result1, result2, result3...) from the cells where the results are displayed ported back into access.
Ideally this could be done live.
I suppose I could try to program the functionality of the spreadheet into a complex function in access, but if I'm honest, I am not really sure how the algorithm in the spreadsheet works. It was designed by anaesthetists who are much cleverer than me....
Hope this makes sense. Any help much appreciated.
Chris Hammond
It's possible to automate Excel from Access.
Const cstrFile As String = "C:\SomeFolder\foo.xls"
Dim xlApp As Object
Dim xlWrkBk As Object
Dim xlWrkSt As Object
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Open cstrFile, ReadOnly:=True
Set xlWrkBk = xlApp.Workbooks(1)
Set xlWrkSt = xlWrkBk.Worksheets(1)
With xlWrkSt
.Range("A1") = 2
.Range("A2") = 19
Debug.Print .Range("A3")
End With
xlWrkBk.Close SaveChanges:=False
However, that seems like it would be cumbersome to repeat for each row of an Access table and I'm uncertain whether doing that live is reasonable.
I would try to adapt the Excel calculations to Access VBA functions and use those custom functions in an Access query. But I don't know how big of a task that would be. I suggest you shouldn't be scared off the the anaesthetists' cleverness; that doesn't mean they actually know much more about VBA than you. At least look to see whether you can tackle it.
To push the data back to Access, you can insert data from within the Excel VBA as follows:
dim val as variant
dim db as DAO.Database
val=thisworkbook.range("a1").value
set db=OpenDatabase("c:\myAccessDB.accdb")
db.execute "insert into patientData (someField) values (" & val & ")",dbFailOnError
db.Close
You'll need to add a reference to the Microsoft Office Access Database Engine Object Library.
Not sure to perfectly understand what you want, but if you just want to export the results of a query to a spreadsheet, you could use the following:
Private Sub ExportAccessDataToExcel()
Dim SqlString As String
SqlString = "CREATE TABLE testMeasurements (TestName TEXT, Status TEXT)"
DoCmd.RunSQL (SqlString)
SqlString = "INSERT INTO testMeasurements VALUES('Average Power','PASS')"
DoCmd.RunSQL (SqlString)
SqlString = "INSERT INTO testMeasurements VALUES('Power Vs Time','FAIL')"
DoCmd.RunSQL (SqlString)
SqlString = "SELECT testMeasurements.TestName, testMeasurements.Status INTO exportToExcel "
SqlString = SqlString & "FROM testMeasurements "
SqlString = SqlString & "WHERE (((testMeasurements.TestName)='Average Power'));"
DoCmd.RunSQL (SqlString)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel7, "exportToExcel", "C:\TestMeasurements.xls", True, "A1:G12"
End Sub
Source: http://www.ehow.com/how_7326712_save-access-query-excel-vba.html
This could be done either directly from the database or from Excel (you would need to open the database with Excel VBA to do so, but most of the Office Suite products interact well with each other).
If you want to push the data of your spreadsheet into an Access database, that's different. You just have to open the database and loop through INSERT query. Here is a quick example, you just need to add the loop:
Dim db as DAO.Database
Set db = OpenDatabase(myDataBase.mdb)
Call db.Execute("INSERT INTO myTable (Field1, Field2) VALUES('Value1', 'Value2')")
I got stuck in the problem beneath, because I don´t use Access or Excel much and I have some basic programming language. So here's the deal:
I just made a fairly simple database in MS Access (2007) with a nice query to retrieve data, depending on which parameters you pass. In Excel (2007), I have this big 'template' which basically has parameters for the query. These parameters change per column & per row!
Perhaps superfluously, e.g.
column A contains paramA (10 different options)
column B contains paramB (8 different options)
column C contains paramC (2 different options)
What I'd like to do is to fill this template with dynamic data from Access, minding the continously changing parameters.
e.g.
column D contains Query (ParamA, ParamB, ParamC)
Best way to go I think is to make a (inline?) function that retrieves results from the query, also passing the parameters depending on the relative cell position. And this function is then copied as a normal inline excel function (like: SUM()).
I just don't know how to call /execute an MS Access query from inside an Excel Macro function.
Could someone help me with it? Thank you very much in advance!
A few notes.
Dim cn As Object
Dim rs As Object
''See: http://www.connectionstrings.com/access
strFile = "C:\Docs\AccessDB.mdb"
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _
& ";User Id=admin;Password=;"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
strSQL = "SELECT SomeField, OtherField FROM SomeTable " _
& "WHERE SomeText='" & Range("A1") & "'"
rs.Open strSQL, cn
s = rs.GetString
MsgBox s
'' Or
Sheets("Sheet2").Cells(2, 1).CopyFromRecordset rs
To add to Remou's answer also see
Modules: Sample Excel Automation - cell by cell which is slow and
Modules: Transferring Records to Excel with Automation
Late binding means you can safely remove the reference and only have an error when the app executes lines of code in question. Rather than erroring out while starting up the app and not allowing the users in the app at all. Or when hitting a mid, left or trim function call.
This also is very useful when you don't know version of the external application will reside on the target system. Or if your organization is in the middle of moving from one version to another.
For more information including additional text and some detailed links see the "Late Binding in Microsoft Access" page